以前咱们分析过喜马拉雅的爬取信息,使用分布式爬取,并且须要修改scrapy-redis的过滤算法为布隆过滤来减小redis内存占用,最后考虑这样仍是不必定够,那么redis集群就是更好的一种选择方式了。node
Redis 集群是一个提供在多个Redis节点间共享数据的程序集。python
Redis集群并不支持处理多个keys的命令,由于这须要在不一样的节点间移动数据,从而达不到像Redis那样的性能,在高负载的状况下可能会致使不可预料的错误.redis
Redis 集群经过分区来提供必定程度的可用性,在实际环境中当某个节点宕机或者不可达的状况下继续处理命令. Redis 集群的优点:算法
自动分割数据到不一样的节点上。 整个集群的部分节点失败或者不可达的状况下可以继续处理命令。
Redis 集群键分布算法使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 它们的编号为0、一、二、3……1638二、16383,这个槽是一个逻辑意义上的槽,实际上并不存在。redis中的每一个key都属于这 16384 个哈希槽的其中一个,存取key时都要进行key->slot的映射计算。数据库
Redis 集群有16384个哈希槽,每一个key经过CRC16校验后对16384取模来决定放置哪一个槽.集群的每一个节点负责一部分hash槽,举个例子,好比当前集群有3个节点,那么:ruby
节点 A 包含 0 到 5500号哈希槽. 节点 B 包含5501 到 11000 号哈希槽. 节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 好比若是我想新添加个节点D, 我须要从节点 A, B, C中得部分槽到D上. 若是我想移除节点A,须要将A中的槽移到B和C节点上,而后将没有任何槽的A节点从集群中移除便可. 因为从一个节点将哈希槽移动到另外一个节点并不会中止服务,因此不管添加删除或者改变某个节点的哈希槽的数量都不会形成集群不可用的状态.微信
为了使在部分节点失败或者大部分节点没法通讯的状况下集群仍然可用,因此集群使用了主从复制模型,每一个节点都会有N-1个复制品.网络
在咱们例子中具备A,B,C三个节点的集群,在没有复制模型的状况下,若是节点B失败了,那么整个集群就会觉得缺乏5501-11000这个范围的槽而不可用.数据结构
然而若是在集群建立的时候(或者过一段时间)咱们为每一个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会由于槽找不到而不可用了app
不过当B和B1 都失败后,集群是不可用的.
Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操做.
第一个缘由是由于集群是用了异步复制. 写操做过程:
客户端向主节点B写入一条命令. 主节点B向客户端回复命令状态. 主节点将写操做复制给他得从节点 B1, B2 和 B3.
主节点对命令的复制工做发生在返回命令回复以后, 由于若是每次处理命令请求都须要等待复制操做完成的话, 那么主节点处理命令请求的速度将极大地下降 —— 咱们必须在性能和一致性之间作出权衡。 注意:Redis 集群可能会在未来提供同步写的方法。 Redis 集群另一种可能会丢失命令的状况是集群出现了网络分区, 而且一个客户端与至少包括一个主节点在内的少数实例被孤立。
举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .
Z1仍然可以向主节点B中写入, 若是网络分区发生时间较短,那么集群将会继续正常运做,若是分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.
CentOS和Mac的安装请看:Linux/Mac安装Redis数据库
Linux通用的安装方式:
mkdir /home/redis-cluster cd /home/redis-cluster # 下载稳定版redis wget http://download.redis.io/releases/redis-stable.tar.gz tar xvf redis-stable.tar.gz cd redis-stable make make install
安装完之后,redis命令会在/usr/local/bin目录下,咱们还须要将src/redis-trib.rb文件拷贝到/usr/local/bin目录下,咱们直接在命令行使用redis-server就能够启动服务
在redis-stable目录下有redis.conf文件,先修改文件配置
port 7000(每一个节点的端口号) daemonize yes(后台运行) bind 192.168.1.110(绑定当前机器 IP) dir /home/redis-cluster/7000/data/(数据文件存放位置) pidfile /var/run/redis_7000.pid(pid 7000和port要对应) cluster-enabled yes(启动集群模式) cluster-config-file nodes-7000.conf(7000和port要对应) cluster-node-timeout 15000 appendonly yes
先建立集群目录
cd /home/redis-cluster mkdir -p 7000/data 7001/data 7002/data 7003/data 7004/data 7005/data
将上面的redis.conf文件分别复制到这几个文件夹中,修改其中端口相关的部分
port 7001 dir /home/redis-cluster/7001/data/ pidfile /var/run/redis_7001.pid pidfile /var/run/redis_7001.pid cluster-config-file nodes-7001.conf
启动节点
redis-server /home/redis-cluster/7000/data/redis.conf redis-server /home/redis-cluster/7001/data/redis.conf redis-server /home/redis-cluster/7002/data/redis.conf redis-server /home/redis-cluster/7003/data/redis.conf redis-server /home/redis-cluster/7004/data/redis.conf redis-server /home/redis-cluster/7005/data/redis.conf
到这里先别急,离成功已经很近了,咱们还须要安装集群所需的软件
CentOS安装
yum install ruby yum install rubygems gem install redis
压缩包安装
下载ruby网址:https://www.ruby-lang.org/en/downloads/
下载rubygems网址:https://rubygems.org/pages/download
# 下载ruby wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz tar xf ruby-2.5.1.tar.gz cd ruby-2.5.1 ./configure make make install #下载rubygems wget https://rubygems.org/rubygems/rubygems-2.7.7.tgz tar xf rubygems-2.7.7.tgz cd rubygems-2.7.7 ruby setup.rb #安装完rubygems后,就可使用gem命令安装redis支持 gem install redis
启动集群
redis-trib.rb create --replicas 1 192.168.1.110:7000 192.168.1.110:7001 192.168.1.110:1002 192.168.1.110:7003 192.168.1.110:7004 192.168.1.110:7005
参数:
--replicas 1 表示主从复制比例为 1:1,即一个主节点对应一个从节点;而后,默认给咱们分配好了每一个主节点和对应从节点服务,以及 solt 的大小,由于在 Redis 集群中有且仅有 16383 个 solt ,默认状况会给咱们平均分配,固然你能够指定,后续的增减节点也能够从新分配。
咱们如今有六个节点,三个主节点三个从节点,默认最少须要六个节点才能组成集群。
错误日志:若是报node 192.168.1.xx:7001 is not empty之类的错误说明集群未正确关闭或是存有日志文件则
针对错误信息执行集群修复命令:./redis-trib.rb fix 192.168.133.128:7001
登陆客户端进行操做:
redis-cli -c -h 192.168.1.110 -p 7000
必定要加上-c参数
到这里单机集群配置已经成功了
与单机配置相比较,须要修改的有如下几点:
其余的命令等均同样
集群搭建好了,可是有一点要注意,对于同一个key只会存在于一个节点机器上,好比set、zset、list这种数据结构。因此最初我想用集群去存储上亿条去重数据等想法是不行了。最终仍是要修改去重算法。
python的redis库是不支持集群操做的,推荐库:redis-py-cluster,一直在维护。还有一个rediscluster库,看GitHub上已经好久没更新了。
安装pip install redis-py-cluster
from rediscluster import StrictRedisCluster startup_nodes = [ {"host":"192.168.1.110", "port":7000}, {"host":"192.168.1.110", "port":7001}, {"host":"192.168.1.110", "port":7002}, {"host":"192.168.1.110", "port":7003}, {"host":"192.168.1.110", "port":7004}, {"host":"192.168.1.110", "port":7005} ] rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True) rc.set('name','admin') rc.set('age',18) print "name is: ", rc.get('name') print "age is: ", rc.get('age')
除了链接这里不同,其余的操做与redis库一致,另外在startup_nodes参数中即便写错几个机器host或port也能链接成功,理论上讲只要有一个节点正常就可使用
若是你以为个人文章还能够,能够关注个人微信公众号,查看更多实战文章:Python爬虫实战之路
也能够扫描下面二维码,添加个人微信公众号