为什么要分片:随着Redis存储的数据越来越庞大,会导致Redis性能越来越差!
目前分片的方法:
1、客户端分片
在应用层面分片,程序里指定什么数据存放在那个Redis 优势:比较灵活 缺点:加个节点扩容就很费劲
2、代理Proxy分片,第三方的Twemproxy使用代理的缺点,你代理什么性能,那么你整个Redis的性能就是什么样的!
3、Redis cluster
4、cidis(豌豆荚)开源
Redis cluster:
这里摘录:http://redisdoc.com/topic/cluster-tutorial.html#id2
集群分片:
Redis集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现:一个Redis集群包含16384个哈希槽(hash slot),数据库中的每个键都属于这16384个哈希槽的其中一个,集群使用公式CRC16(key)%16384来计算键key属于那个槽,其中CRC16(key)语句用于计算键key的CRC16校验和。
集群中的每个节点负责处理一部分哈希槽。举个例子,一个集群可以有三个哈希槽,其中:
*节点A负责处理0号至5500号哈希槽。
*节点B负责处理5501号至11000号哈希槽。
*节点C负责处理11001号至16384号哈希槽。
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。比如说:
*如果用户将新节点D添加到集群中,那么集群只需要将节点A、B、C中的某些槽移动到节点D就可以了。
*与此类似,如果用户要从集群中移除节点A,那么集群只需要将节点A中的所有哈希槽移动到节点B和节点C,然后再移除空白(不包含任何哈希槽)的节点A就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞,所以无论是添加新节点还是移除已存在节点,又或者改变某个节点包含的哈希槽数量,都不会造成集群下线。
Redis集群中的主从复制
为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下,仍然可以正常运作,Redis集群对节点使用了主从复制功能:集群中的每个节点都有1个至N个复制品(replica),其中一个复制品为主节点(master),而其余的N-1个复制品为从节点(slave)。
在之前列举的节点A、B、C的例子中,如果节点B下线了,那么集群将无法正常运行,因为集群找不到节点来处理5501号至11000号的哈希槽。
另一方面,假如在创建集群的时候(或者至少在节点B下线之前),我们为主节点B添加了从节点B1,那么当主节点B下线的时候,集群就会将B1设置为新的主节点,并让它代替下线的主节点B,继续处理5501号至11000号的哈希槽,这样集群就不会因为主节点B的下线而无法正常运作了。
不过如果节点B和B1都下线的话,Redis集群还是会停止运作。
Redis集群的一致性保证(guarantee)
Redis集群不保证数据的强一致性(strong consistency):在特定的条件下,Redis集群可能会丢失已经被执行过的写命令。
使用异步复制(asynchronous replication)是Redis集群可能会丢失写命令的其中一个原因。考虑以下这个写命令的例子:
* 客户端向主节点B发送一条写命令。
* 主节点B执行写命令,并向客户端返回命令回复。
* 主节点B将刚刚执行的写命令复制给它的从节点B1、B2和B3.
如你所见,主节点对命令的复制工作发生在返回命令回复之后,因为如果每次处理命令请求都需要等待复制操作完成的话,那么主节点处理命令请求的速度将极大地降低--我们必须在性能和一致性之间做出权衡。
如果真的有必要的话,Redis集群可能会在将来提供同步地(synchronou)执行写命令的方法。
Redis集群另外一种可能会丢失命令的情况是,集群出现网络分裂(network partition),并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。
举个例子,架设集群包括A、B、C、A1、B1、C1六个节点,其中A、B、C为主节点,而A1、B1、C1分别为三个主节点的从节点,另外还有一个客户端Z1。
假设集群中发生网络分裂,那么集群可能会分裂为两方,大多数(majority)的一方包括节点A、C、A1、B1和C1,而少数(minority)的一份则包含节点B和客户端Z1。在网络分裂期间,主节点B仍然会接受Z1发送的写指定;
* 如果网络分裂出现的时间很短,那么集群会继续正常运行;
* 但是,如果网络分裂出现的时间足够长,使得大多数一方将从节点B1设置为新的主节点,并使用B1来代替原来的主节点B,那么Z1发送给主节点B的写命令将丢失。
注意,在网络分裂出现期间,客户端Z1可以向主节点B发送写命令的最大时间是有限制的,这一时间限制称为节点超时时间(node timeout),是Redis集群的一个重要的配置选项:
* 对于大多数一方来说,如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群,那么它将停止处理写命令,并向客户端报告错误。
1、安装环境(centos6.7)三台机器做集群
# tar xf redis-3.0.7.tar.gz -C /usr/local # mv redis-3.0.7 redis # cd /usr/local # make # make install # cp utils/redis_init_script /etc/init.d/redis # vim /etc/init.d/redis # chkconfig: 2345 88 45 #加上这一行才能启动 # chmod +x /etc/init.d/redis # chkconfig --add redis # 先修改配置文件,在配置文件里面:新增三行,修改3行 # vim /usr/local/redis/redis.conf cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 port 7001 logfile "redis_7001.log" dir "/data/redis/7001" appendonly yes #并且开启aof # mkdir /etc/redis/{7001,7002} -pv # mkdir /data/redis/{7001,7002} -pv # mkdir /etc/redis/{7003,7004} -pv # mkdir /data/redis/{7003,7004} -pv # mkdir /etc/redis/{7005,7006} -pv # mkdir /data/redis/{7005,7006} -pv # cd /etc/redis #把相关的信息都同一修改为:6379 (端口、日志文件、存储dir目录等) # sed ‘s/6379/7001/g‘ /usr/local/redis/redis.conf > /etc/redis/7001/redis.conf # sed ‘s/6379/7002/g‘ /usr/local/redis/redis.conf > /etc/redis/7002/redis.conf # sed ‘s/6379/7003/g‘ /usr/local/redis/redis.conf > /etc/redis/7003/redis.conf # sed ‘s/6379/7004/g‘ /usr/local/redis/redis.conf > /etc/redis/7004/redis.conf # sed ‘s/6379/7005/g‘ /usr/local/redis/redis.conf > /etc/redis/7005/redis.conf # sed ‘s/6379/7006/g‘ /usr/local/redis/redis.conf > /etc/redis/7006/redis.conf #启动,我这里是三台机器,所以需要分别在机器上启动 # /usr/local/redis/src/redis-server /etc/redis/700[1-6]/redis.conf
2、安装管理工具,源码自带了一个管理Cluster集群的工具,是用ruby写的所以需要安装ruby
# yum -y install ruby rubygems 安装ruby的管理工具Redis # gem install redis
3、复制管理工具
# cp /usr/local/redis/src/redis-trib.rb /usr/bin/redis-trib 查看redis-trib帮助 # redis-trib help # redis-trib help Usage: redis-trib <command> <options> <arguments ...> info host:port import host:port --copy --from <arg> --replace set-timeout host:port milliseconds check host:port call host:port command arg arg .. arg del-node host:port node_id rebalance host:port --threshold <arg> --simulate --pipeline <arg> --use-empty-masters --weight <arg> --timeout <arg> --auto-weights fix host:port --timeout <arg> add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> help (show this help) create host1:port1 ... hostN:portN --replicas <arg> reshard host:port --to <arg> --slots <arg> --yes --from <arg> --pipeline <arg> --timeout <arg>
4、创建集群
# redis-trib create --replicas 1 192.168.130.242:7001 192.168.130.242:7002 192.168.130.243:7003 192.168.130.243:7004 192.168.130.244:7005 192.168.130.244:7006 >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 192.168.130.244:7005 192.168.130.243:7003 192.168.130.242:7001 Adding replica 192.168.130.243:7004 to 192.168.130.244:7005 Adding replica 192.168.130.244:7006 to 192.168.130.243:7003 Adding replica 192.168.130.242:7002 to 192.168.130.242:7001 M: a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 slots:10923-16383 (5461 slots) master S: a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 replicates a3e907fff7e7e90512570fa7284cca11dc2b268f M: 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 slots:5461-10922 (5462 slots) master S: b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 replicates 0892e72f9adafc986a3d6d0ce410c073d2b2414e M: 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 slots:0-5460 (5461 slots) master S: 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 replicates 6776a3698d16d8af4655ca80ae326b48d28f2fdf Can I set the above configuration? (type ‘yes‘ to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.. >>> Performing Cluster Check (using node 192.168.130.242:7001) M: a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 slots:10923-16383 (5461 slots) master M: a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slots: (0 slots) master replicates a3e907fff7e7e90512570fa7284cca11dc2b268f M: 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 slots:5461-10922 (5462 slots) master M: b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slots: (0 slots) master replicates 0892e72f9adafc986a3d6d0ce410c073d2b2414e M: 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 slots:0-5460 (5461 slots) master M: 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slots: (0 slots) master replicates 6776a3698d16d8af4655ca80ae326b48d28f2fdf [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. #create --replicas 1 这里--replicas 1 是指定复制几份,相当于每个master有几个从 #redis cluster最低要求有3个master #master的定义 host1:port host2:port host3:port host4:post 如果--replicas 1 那么: #host1:port == master host2:port 是 host1:port 的从 #如果--replicas 2那么: #host1:port == master host2:port & host3:port 都是 host1:port 的从 #M:这个是cluster自动生成的ID,集群在通信的时候是使用这个ID来区分的
4、连接cluster,(连接任意的Cluster集群中的服务器即可)
# redis-cli -c -h 192.168.130.242 -p 7001 #加-c,可以连接集群的任意节点 192.168.130.242:7001> cluster nodes #查看cluster节点 b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slave 0892e72f9adafc986a3d6d0ce410c073d2b2414e 0 1465812188761 5 connected 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 master - 0 1465812186754 5 connected 0-5460 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slave 6776a3698d16d8af4655ca80ae326b48d28f2fdf 0 1465812188259 6 connected a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 myself,master - 0 0 1 connected 10923-16383 a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slave a3e907fff7e7e90512570fa7284cca11dc2b268f 0 1465812187756 2 connected 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 master - 0 1465812187256 3 connected 5461-10922 192.168.130.242:7001> cluster info #查看cluster信息 cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_sent:5107 cluster_stats_messages_received:5107
5、集群扩容
#在另外一台机器上添加一个redis,目前我添加的是一台两个节点(7007,7008) 开始扩容 # redis-trib add-node 192.168.130.240:7007 192.168.130.242:7001 >>> Adding node 192.168.130.240:7007 to cluster 192.168.130.242:7001 >>> Performing Cluster Check (using node 192.168.130.242:7001) M: a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slots: (0 slots) slave replicates 0892e72f9adafc986a3d6d0ce410c073d2b2414e M: 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 slots:0-5460 (5461 slots) master 1 additional replica(s) S: 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slots: (0 slots) slave replicates 6776a3698d16d8af4655ca80ae326b48d28f2fdf S: a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slots: (0 slots) slave replicates a3e907fff7e7e90512570fa7284cca11dc2b268f M: 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 slots:5461-10922 (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Send CLUSTER MEET to node 192.168.130.240:7007 to make it join the cluster. [OK] New node added correctly. 命令解释: redis-trib add-node 要加的节点和端口,现在任意节点和端口 查看添加完成之后的结果: # redis-cli -c -h 192.168.130.242 -p 7001 192.168.130.242:7001> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:7 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_sent:8227 cluster_stats_messages_received:8227 192.168.130.242:7001> cluster nodes b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slave 0892e72f9adafc986a3d6d0ce410c073d2b2414e 0 1465813049184 5 connected 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 master - 0 1465813050187 5 connected 0-5460 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 192.168.130.240:7007 master - 0 1465813048183 0 connected 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slave 6776a3698d16d8af4655ca80ae326b48d28f2fdf 0 1465813050187 6 connected a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 myself,master - 0 0 1 connected 10923-16383 a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slave a3e907fff7e7e90512570fa7284cca11dc2b268f 0 1465813048684 2 connected 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 master - 0 1465813049184 3 connected 5461-10922
6、新加上来的没有数据-及没有槽位,我们可以用命令让他重新分片
# redis-trib reshard 192.168.130.240:7007 >>> Performing Cluster Check (using node 192.168.130.240:7007) M: 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 192.168.130.240:7007 slots: (0 slots) master 0 additional replica(s) M: 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 slots:0-5460 (5461 slots) master 1 additional replica(s) S: b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slots: (0 slots) slave replicates 0892e72f9adafc986a3d6d0ce410c073d2b2414e M: 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 slots:5461-10922 (5462 slots) master 1 additional replica(s) S: 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slots: (0 slots) slave replicates 6776a3698d16d8af4655ca80ae326b48d28f2fdf S: a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slots: (0 slots) slave replicates a3e907fff7e7e90512570fa7284cca11dc2b268f M: a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 slots:10923-16383 (5461 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)? How many slots do you want to move (from 1 to 16384)? 1 What is the receiving node ID? a3e907fff7e7e90512570fa7284cca11dc2b268f (这里的ID) Please enter all the source node IDs. Type ‘all‘ to use all the nodes as source nodes for the hash slots. Type ‘done‘ once you entered all the source nodes IDs. Source node #1:all Ready to move 1 slots. Source nodes: M: 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 192.168.130.240:7007 slots: (0 slots) master 0 additional replica(s) M: 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 slots:0-5460 (5461 slots) master 1 additional replica(s) M: 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 slots:5461-10922 (5462 slots) master 1 additional replica(s) Destination node: M: a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 slots:10923-16383 (5461 slots) master 1 additional replica(s) Resharding plan: Moving slot 5461 from 6776a3698d16d8af4655ca80ae326b48d28f2fdf Do you want to proceed with the proposed reshard plan (yes/no)? yes Moving slot 5461 from 192.168.130.243:7003 to 192.168.130.242:7001:
7、在添加一个服务器做从
在添加一个7008,让他做7001的从 # redis-trib add-node 192.168.130.240:7008 192.168.130.242:7001 加进来之后默认就是master但是它没有任何槽位 192.168.130.242:7001> cluster nodes b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slave 0892e72f9adafc986a3d6d0ce410c073d2b2414e 0 1465814206935 5 connected 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 master - 0 1465814207435 5 connected 0-5460 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 192.168.130.240:7007 master - 0 1465814205933 8 connected 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slave 6776a3698d16d8af4655ca80ae326b48d28f2fdf 0 1465814206434 6 connected d215116baa7417f9df7fb3c123cdd043f2c44c9d 192.168.130.240:7008 master - 0 1465814206434 0 connected a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 myself,master - 0 0 7 connected 5461 10923-16383 a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slave a3e907fff7e7e90512570fa7284cca11dc2b268f 0 1465814205933 7 connected 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 master - 0 1465814206935 3 connected 5462-10922 然后连接到7008的这个redis实例上,然后复制7007的ID # redis-cli -c -h 192.168.130.240 -p 7008 192.168.130.240:7008> cluster replicate 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 OK 然后在看看集群: 192.168.130.240:7008> cluster nodes b8c71ad4e497f7205bfa8546ba90de7e2340a9ac 192.168.130.243:7004 slave 0892e72f9adafc986a3d6d0ce410c073d2b2414e 0 1466757446668 5 connected a821296f4a4fcbb122b31d19d89ca2d87868a8cd 192.168.130.242:7002 slave a3e907fff7e7e90512570fa7284cca11dc2b268f 0 1466757448270 7 connected a3e907fff7e7e90512570fa7284cca11dc2b268f 192.168.130.242:7001 master - 0 1466757447167 7 connected 5461 10923-16383 54d910362fe57628a7be3e26450e2bff8bcfb568 192.168.130.244:7006 slave 6776a3698d16d8af4655ca80ae326b48d28f2fdf 0 1466757448170 3 connected d215116baa7417f9df7fb3c123cdd043f2c44c9d 192.168.130.240:7008 myself,slave 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 0 0 0 connected 6776a3698d16d8af4655ca80ae326b48d28f2fdf 192.168.130.243:7003 master - 0 1466757447669 3 connected 5462-10922 9ddb7fb1f4741b99b2ed1e458197680cc6ace6e7 192.168.130.240:7007 master - 0 1466757446667 8 connected 0892e72f9adafc986a3d6d0ce410c073d2b2414e 192.168.130.244:7005 master - 0 1466757446668 5 connected 0-5460
8、Cluster的主从复制这个操作也是向master发送请求,然后master做个BGSAVE然后拿过来重载一下!如果master特别大的所以要起多个Redis实例,每个里面存一部分。也需要注意,涉及到多key的操作!是不行的,因为你不同的key存在不同的地方!
# redis-cli -c -h 192.168.130.242 -p 7001 192.168.130.242:7001> set key100 bjwf -> Redirected to slot [5728] located at 192.168.130.243:7003 OK 192.168.130.243:7003> set key101 bjwf -> Redirected to slot [1601] located at 192.168.130.244:7005 OK 192.168.130.244:7005> set key102 bjwf -> Redirected to slot [13858] located at 192.168.130.242:7001 OK 192.168.130.242:7001> set key103 bjwf -> Redirected to slot [9731] located at 192.168.130.243:7003 OK 192.168.130.243:7003> set key104 bjwf OK 192.168.130.243:7003> set key105 bjwf -> Redirected to slot [1733] located at 192.168.130.244:7005 OK 192.168.130.244:7005> set key106 bjwf -> Redirected to slot [13990] located at 192.168.130.242:7001 OK 192.168.130.242:7001> set key107 bjwf -> Redirected to slot [9863] located at 192.168.130.243:7003 OK 192.168.130.243:7003> set key108 bjwf OK 192.168.130.243:7003> set key109 bjwf -> Redirected to slot [1865] located at 192.168.130.244:7005 OK
###今天先写到这了,暂时会的就这些,以后回了在写其他的。以上仅为个人收集整理,如有错漏,大神勿喷!!!!!!!
本文出自 “把酒问苍天” 博客,请务必保留此出处http://79076431.blog.51cto.com/8977042/1792608
原文地址:http://79076431.blog.51cto.com/8977042/1792608