Sentinel是一个管理多个redis实例的工具,它可以实现对redis的监控、通知、自动故障转移。sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态,如果redis master不能工作,则会自动启动故障转移进程,将其中的一个slave提升为master,其他的slave重新设置新的master实例。也就是说,它提供了:
监控(Monitoring): Sentinel 会不断地检查你的主实例和从实例是否正常。
通知(Notification): 当被监控的某个 Redis 实例出现问题时, Sentinel 进程可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主redis实例失效时, Sentinel 会开始记性一次failover, 它会将失效主实例的其中一个从实例升级为新的主实例, 并让失效主实例的其他从实例改为复制新的主实例; 而当客户端试图连接失效的主实例时, 集群也会向客户端返回新主实例的地址, 使得集群可以使用新主实例代替失效实例。
Redis Sentinel自身也是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程, 这些进程使用流言协议(gossip protocols)来接收关于主Redis实例是否失效的信息, 然后使用投票协议来决定是否执行自动failover,以及评选出从Redis实例作为新的主Redis实例。
1.启动sentinel的方法
当前Redis stable版已经自带了redis-sentinel这个工具。虽然 Redis Sentinel 已经提供了一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis实例, 你可以在启动一个普通 Redis实例时通过给定 –sentinel 选项来启动 Redis Sentinel 实例。也就是说:
redis-sentinel /path/to/sentinel.conf
等同于
redis-server /path/to/sentinel.conf --sentinel
其中sentinel.conf是redis的配置文件,Redis sentinel会需要写入配置文件来保存sentinel的当前状态。当配置文件无法写入时,Sentinel启动失败。
2. sentinel的配置
一个简单的sentinel配置文件实例如下:
1
2
3
4
5
6
port 26329
sentinel monitor myredis 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel notification-script myredis <script-path>
sentinel 选项的名字 主Redis实例的名字 选项的值
配置文件的格式为:
第一行配置指示 Sentinel 去监视一个名为 mymaster 的主redis实例, 这个主实例的 IP 地址为本机地址127.0.0.1 , 端口号为 6379 , 而将这个主实例判断为失效至少需要 2 个 Sentinel 进程的同意,只要同意 Sentinel 的数量不达标,自动failover就不会执行。同时,一个Sentinel都需要获得系统中大多数Sentinel进程的支持, 才能发起一次自动failover, 并预留一个新主实例配置的编号。而当超过半数Redis不能正常工作时,自动故障转移是无效的。
各个选项的功能如下:
down-after-milliseconds 选项指定了 Sentinel 认为Redis实例已经失效所需的毫秒数。
当实例超过该时间没有返回PING,或者直接返回错误, 那么 Sentinel 将这个实例标记为主观下线(subjectively down,简称 SDOWN )。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移: 只有在足够数量的 Sentinel 都将一个实例标记为主观下线之后,实例才会被标记为客观下线(objectively down, 简称 ODOWN ), 这时自动故障迁移才会执行。具体的行为如下:
(1). 每个 Sentinel 每秒一次向它所监控的主实例、从实例以及其他 Sentinel 实例发送一个 PING 命令。当一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。如果一个主实例被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主实例被标记为客观下线。
(2).在一般情况下, 每个 Sentinel 进程会以每 10 秒一次的频率向它已知的所有主实例和从实例发送 INFO 命令。 当一个主实例被 Sentinel实例标记为客观下线时, Sentinel 向下线主实例的所有从实例发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
(3).当没有足够数量的 Sentinel 同意主实例已经下线, 主Redis服务实例的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。
parallel-syncs 选项指定了在执行故障转移时, 最多可以有多少个从Redis实例在同步新的主实例, 在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长。
尽管复制过程的绝大部分步骤都不会阻塞从实例, 但从redis实例在载入主实例发来的 RDB 文件时, 仍然会造成从实例在一段时间内不能处理命令请求: 如果全部从实例一起对新的主实例进行同步, 那么就可能会造成所有从Redis实例在短时间内全部不可用的情况出现。
所以从实例被设置为允许使用过期数据集(参见对 redis.conf 文件中对 slave-serve-stale-data 选项),可以缓解所有从实例都在同一时间向新的主实例发送同步请求的负担。你可以通过将这个值设为 1 来保证每次只有一个从Redis实例处于不能处理命令请求的同步状态。
failover-timeout如果在该时间(ms)内未能完成failover操作,则认为该failover失败。
notification-script: 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用。
3. Sentinel集群的运行机制
一个 Sentinel进程可以与其他多个 Sentinel进程进行连接, 每个 Sentinel进程之间可以互相检查对方的可用性, 并进行信息交换。
和其他集群不同的是,你无须设置其他Sentinel的地址,Sentinel进程可以通过发布与订阅来自动发现正在监视相同主实例的其他Sentinel。同样,你也不必手动列出主实例属下的所有从实例,因为Sentinel实例可以通过询问主实例来获得所有从实例的信息。
每个 Sentinel 都订阅了被它监视的所有主服务器和从服务器的 __sentinel__:hello 频道, 查找之前未出现过的 sentinel进程。 当一个 Sentinel 发现一个新的 Sentinel 时,它会将新的 Sentinel 添加到一个列表中,这个列表保存了 Sentinel 已知的,监视同一个主服务器的所有其他Sentinel。
4. 启动Redis和sentinel
下面的测试环境为ubuntu 14.04 LTS,Redis 2.8.19。下面首先配置一个小型的M/2S环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/etc/redis/redis-m.conf
daemonize yes
pidfile /var/run/redis/redis-server-m.pid
port 6379
loglevel notice
logfile /var/log/redis/redis-server-m.log
databases 16
##disable snapshot
save ""
dir /app/redis-m
appendonly yes
appendfilename "appendonly.aof"
##not to be a slave
#slaveof no one

/etc/redis/redis-s1.conf
daemonize yes
pidfile /var/run/redis/redis-server-s1.pid
port 6380
loglevel warning
logfile /var/log/redis/redis-server-s1.log
databases 16
##disable snapshot
save ""
dir /app/redis-s1
appendonly yes
appendfilename "appendonly.aof"
##to be a slave

/etc/redis/redis-s2.conf
daemonize yes
pidfile /var/run/redis/redis-server-s2.pid
port 6381
loglevel warning
logfile /var/log/redis/redis-server-s2.log
databases 16
##disable snapshot,enable AOF
save ""
dir /app/redis-s2
appendonly yes
appendfilename "appendonly.aof"
##to be a slave
slaveof 127.0.0.1 6379
启动后,查看进程和复制状态是否正常:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ps -ef | grep redis
root 17560 1 0 09:48 ? 00:00:00 redis-server *:6379
root 17572 1 0 09:48 ? 00:00:00 redis-server *:6380
root 17609 1 0 09:49 ? 00:00:00 redis-server *:6381

redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=547,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=547,lag=1
master_repl_offset:547
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:546
前面我们了解了,Sentinel可以通过master Redis实例来获得它的从实例的信息。所以每一个Sentinel只配置主实例的监控即可。Sentinel之间端口有所不同。
1
2
3
4
5
6
port 26379
sentinel monitor myredis 127.0.0.1 6379 2
sentinel down-after-milliseconds myredis 60000
sentinel failover-timeout myredis 180000
sentinel parallel-syncs myredis 1
sentinel notification-script myredis /etc/redis/log-issues.sh
其中,通知脚本简单的记录一下failover事件。
1
2
3
#!/bin/bash

echo "master failovered at `date`" > /root/redis_issues.log
另外两个端口分别为port 26380。然后通过redis-sentinel命令来启动两个sentinel实例。
1
2
3
4
# nohup redis-sentinel /etc/redis/sentinel1.conf > /root/sentinel1.log 2>&1 &
[1] 18207
# nohup redis-sentinel /etc/redis/sentinel2.conf > /root/sentinel2.log 2>&1 &
[2] 18212
通过日志输出可以看出已经成功监控master和两个slave。并和另一个sentinel进程通信。
1
2
3
4
5
[18207] 08 May 13:28:29.336 # Sentinel runid is d72be991001b994568d3de1b746f611884b0343a
[18207] 08 May 13:28:29.336 # +monitor master myredis 127.0.0.1 6379 quorum 2
[18207] 08 May 13:28:29.339 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
[18207] 08 May 13:28:29.339 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
[18207] 08 May 13:28:36.602 * +sentinel sentinel 127.0.0.1:26479 127.0.0.1 26479 @ myredis 127.0.0.1 6379
5. 连接Sentinel和主动failover
在默认情况下,Sentinel 使用TCP端口26379(普通 Redis 服务器使用的是 6379)。Sentinel 接受 Redis 协议格式的命令请求, 所以你可以使用 redis-cli 或者任何其他 Redis 客户端来与 Sentinel 进行通讯。
有两种方式可以和 Sentinel 进行通讯:
第一种方法是通过直接发送命令来查询被监视 Redis 服务器的当前状态, 以及进行主动转移等操作。这些命令包括:
(1). PING :返回 PONG 。
1
2
3
# redis-cli -p 26379
127.0.0.1:26379> ping
PONG
(2). SENTINEL masters :列出所有被监视的主Redis服务实例,以及这些主服务实例的当前状态。SENTINEL slaves :列出给定主服务实例的所有从实例,以及这些从实例的当前状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "myredis"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "a88ffd6548e333f3ac895cf1b890ef32a527dd66"
......
37) "parallel-syncs"
38) "1"
39) "notification-script"
40) "/etc/redis/log-issues.sh"
127.0.0.1:26379> sentinel slaves myredis
1) 1) "name"
2) "127.0.0.1:6381"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6381"
......
2) 1) "name"
2) "127.0.0.1:6380"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6380"
.......
(3). SENTINEL get-master-addr-by-name : 返回给定名字的主实例的 IP 地址和端口号。 如果这个主实例正在执行故障转移操作, 或者针对这个主实例的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号。
1
2
3
127.0.0.1:26379> sentinel get-master-addr-by-name myredis
1) "127.0.0.1"
2) "6379"
(4). SENTINEL reset : 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清除该sentinel的所保存的所有状态信息,并进行一次重新的发现过程。
127.0.0.1:26379> sentinel reset myredis
(integer) 1
(5). SENTINEL failover :进行一次主动的failover。即在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移 。发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置,其他 Sentinel 会根据这个配置进行相应的更新。
1
2
127.0.0.1:26379> sentinel failover myredis
OK
## master切换到了localhost:6381上。
1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:26379> sentinel get-master-addr-by-name myredis
1) "127.0.0.1"
2) "6381"
## redis-cli中
redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
第二种方法是使用发布与订阅功能, 通过接收 Sentinel 发送的通知: 当执行故障转移操作, 或者某个被监视的实例被判断为主观下线或者客观下线时, Sentinel 就会发送相应的信息。
一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。
通过执行 PSUBSCRIBE * 命令可以接收所有事件信息。例如:
1
2
3
4
5
127.0.0.1:26379> PSUBSCRIBE *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1
###此时进行一次主动的failover,各个频道的输出中涉及了新纪元(epoch)通知、投票、选举、新主和新slave的通告、角色转变通知,最终完成了这次主动failover过程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
1) "pmessage"
2) "*"
3) "+new-epoch"
4) "2"
1) "pmessage"
2) "*"
3) "+try-failover"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+vote-for-leader"
4) "d72be991001b994568d3de1b746f611884b0343a 2"
1) "pmessage"
2) "*"
3) "+elected-leader"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-select-slave"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+selected-slave"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-send-slaveof-noone"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-wait-promotion"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "-role-change"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381 new reported role is master"
1) "pmessage"
2) "*"
3) "+promoted-slave"
4) "slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-state-reconf-slaves"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-sent"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-inprog"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+slave-reconf-done"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+failover-end"
4) "master myredis 127.0.0.1 6381"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "myredis 127.0.0.1 6381 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "+slave"
4) "slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "+slave"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380"
1) "pmessage"
2) "*"
3) "-role-change"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380 new reported role is master"
1) "pmessage"
2) "*"
3) "+role-change"
4) "slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380 new reported role is slave"
由此可见,一次failover的过程如下:
一次故障转移操作由以下步骤组成:
(1). 由sentinel主动发起failover或者发现主服务器已经进入客观下线状态。
(2). sentinel对我们的当前纪元(epoch)进行自增,并尝试在这个纪元中当选为此次failover的总指挥。
(3). 如果当选失败, 那么在设定的故障迁移超时时间的两倍之后, 重新尝试当选。 如果当选成功, 那么执行以下步骤。
(4). 选出一个从redis实例,并将它升级为主redis实例。
(5). 向被选中的从redis实例发送 SLAVEOF NO ONE 命令,让它转变为主redis实例。
(6). 通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。
(7). 向已下线主服务器的从服务器发送SLAVEOF命令, 让它们去复制新的主服务器。
(8). 当所有从redis实例都已经开始复制新的主redis实例时, 领头Sentinel 终止这次故障迁移操作。
6. 被动failover场景测试
当前状态,主failover为6380
1
2
3
4
5
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
关闭6380Redis实例,等待down-after-milliseconds后,sentinel的日志有如下输出,证明切换成功。
1
2
3
4
5
6
7
[18207] 08 May 14:20:32.784 # +sdown master myredis 127.0.0.1 6380
[18207] 08 May 14:20:32.855 # +odown master myredis 127.0.0.1 6380 #quorum 2/2
[18207] 08 May 14:20:32.855 # +new-epoch 3
......投票、选举......
[18207] 08 May 14:20:34.989 # +switch-master myredis 127.0.0.1 6380 127.0.0.1 6381
[18207] 08 May 14:20:34.989 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381
[18207] 08 May 14:20:34.992 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381
启动6380实例,它会自己作为slave连接行6381这个master节点上。
1
2
3
4
5
6
7
8
$ redis-server /etc/redis/redis-s1.conf
$ redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
测试成功。最后需要注意的是,sentinel集群自身也需要多数机制,也就是2个sentinel进程时,挂掉一个另一个就不可用了。
7. Sentinel的客户端
如果要做到应用程序(客户端)对Redis的failover透明Transparent),客户端需要监控sentinel的频道信息,并自动连接新的主节点。官方提供了一个专门的topic来讲解这个问题:Guidelines for Redis clients with support for Redis Sentinel,而一些常用的开发语言也已经有了整合sentinel的redis driver:
Python redis 2.10.3
Java Jedis
以Python为例,首先安装redis-py。
pip install redis
一个简单的测试代码如下,首先获得一个Sentinel对象,然后
1
2
3
4
5
6
7
vim sentinel.py
from redis.sentinel import Sentinel
sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
master = sentinel.master_for('myredis', socket_timeout=0.1)
master.set('foo', 'bar')
slave = sentinel.slave_for('myredis', socket_timeout=0.1)
slave.get('foo')
执行后成功得到bar这个值。
1
2
python sentinel.py
bar
上面的master和slave都是标准的建立好连接的StrictRedis实例,slave则是sentinel查询到的第一个可用的slave。如果正在连接的master不可用时,客户端会先抛出redis.exceptions.ConnectionError异常(此时还没开始failover),然后抛出redis.sentinel.MasterNotFoundError异常(failover进行中),在sentinel正常failover之后,实例正常。所以要开发一个sentinel的高可用客户端,可以参考上面那篇官方的指导。

Redis Sentinel配置小记的更多相关文章

  1. redis sentinel 配置

    在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的”读/写功能都将受影响,这在生产环境中显然不能接受.幸好redis提供了sentine ...

  2. Redis Sentinel 高可用服务搭建

    阅读目录: 关于 Redis 的概念 关于 Redis Sentinel 的概念 搭建 Redis Server(master) 搭建 Redis Server(slave) 搭建 Redis Sen ...

  3. 【转载】Redis Sentinel 高可用服务架构搭建

    作者:田园里的蟋蟀 出处:http://www.cnblogs.com/xishuai/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接. 阅读 ...

  4. Redis 安装,主从配置及Sentinel配置自动Failover

    1.安装redis 首页地址:http://redis.io/ 下载地址:http://download.redis.io/ 下载最新的源码包 tar -zxvf redis-stable.tar.g ...

  5. redis sentinel集群配置及haproxy配置

    ip分布情况: sentinel-1/redis 主 10.11.11.5 sentinel-2/redis 从 10.11.11.7 sentinel-3/redis 从 10.11.11.8 ha ...

  6. laravel redis sentinel 和 redis cluster 配置

    laravel redis sentinel配置: 'redis' => [ 'cluster' => false, 'options' => [ 'replication' =&g ...

  7. Redis Sentinel主从高可用方案

    Redis Sentinel主从高可用方案 本文介绍一种通过Jed和Sentinel实现Redis集群(主从)的高可用方案,该方案需要使用Jedis2.2.2及以上版本(强制),Redis2.8及以上 ...

  8. spring集成redis——主从配置以及哨兵监控

    Redis主从模式配置: Redis的主从模式配置是非常简单的,首先我们需要有2个可运行的redis环境: master node : 192.168.56.101 8887 slave node: ...

  9. redis sentinel集群

    ip分布情况: sentinel-1/redis 主 10.11.11.5 sentinel-2/redis 从 10.11.11.7 sentinel-3/redis 从 10.11.11.8 ha ...

随机推荐

  1. 一段文字中的几个keyword显示高亮

    将一段文字中的几个keyword显示高亮 演示样例:将"我的愿望是当个绿巨人,所以我想让我的皮(derma)肤是绿色"中的"皮肤"显示绿色. <span ...

  2. string.prototype.replace 和正则表达式

    字符串的replace方法是操作字符串的常用方法之一,但这个方法只有当与正则合并使用时,才能体现出它的强大之处. 语法:str.replace(regexp|substr, newsubStr|fun ...

  3. 学习Git的最佳资料

    1. ProGit中文版:https://git-scm.com/book/zh/v2 2. 廖雪峰的Git教程: http://www.liaoxuefeng.com/wiki/0013739516 ...

  4. C# 接口使用方法

    之前一直不理解接口这一概念,今天无意中翻书,网上查资料悟道其中的道理,现在工作没有用到interface这一块,怕以后会遇到忘记实现的方法便记录下来,哪里写的不对希望读者指出,话不多说,接下来看我对接 ...

  5. Spark术语

    1.resilient distributed dataset (RDD) The core programming abstraction in Spark, consisting of a fau ...

  6. Asp.Net Web API(六)

    Asp.Net Web API不可以需要IIS.可以自己在主机上承载一个Web API 创建WebAPI.Server项目 创建一个控制器项目的服务端 在Nuget中添加Microsoft.AspNe ...

  7. 解决win7中防火墙的0x6D9问题的方法

    问题: 打开windows防火墙管理单元时出错:代码0x6d9" 解决方法: 下一步-->下一步-->完成.

  8. iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇

    iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...

  9. 本地如何操作服务器的mysql,详细教程

    前置条件: 1.在阿里云服务器de系统是win service 2012. 2.服务器里自己安装了my sql 5.7 3.本地也安装了my sql 5.7 需求:想通过本地的mysql连接上远程的服 ...

  10. Python 多线程进程高级指南(二)

    本文是如何<优雅地实现Python通用多线程/进程并行模块>的后续.因为我发现,自认为懂了一点多线程开发的皮毛,写了那么个multi_helper的玩意儿,后来才发现我靠原来就是一坨屎.自 ...