一.使用redis-cluster的原因
1.并发问题
redis官方声称可以达到 10万/每秒,每秒执行10万条命令 假如业务需要每秒100万的命令执行呢?
2.数据量问题
一台服务器内存正常是16~256G,假如你的业务需要500G内存,
新浪微博作为世界上最大的redis存储,就超过1TB的数据,去哪买这么大的内存条?各大公司有自己的解决方案,推出各自的集群功能,
核心思想都是将数据分片(sharding)存储在多个redis实例中,每一片就是一个redis实例。
由此产生的集群方案:
-
twemproxy由Twitter开源
- Codis由豌豆开源
- redis-cluster 官方3.0的集群方案
3.方案实现的的问题
需要配置一台超大计算机,超大cpu,但是实现起来很难,而且危险性高
正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力,一堆机器做一件事
二.客户端分片
redis3.0集群采用P2P模式,完全去中心化,将redis所有的key分成了16384个槽位,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新
redis实例集群主要思想是将redis数据的key进行散列,通过hash函数特定的key会映射到指定的redis节点上
三.数据分布原理
四.数据分布理论
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。
常见的分区规则有哈希分区和顺序分区。Redis Cluster
采用哈希分区规则,因此接下来会讨论哈希分区规则。
1.顺序分区
2.哈希分区
hash分区又分为以下几种
1.节点取余分区算法
2.一致性哈希
3.虚拟槽分区
Redis Cluster
采用虚拟槽分区
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。 Redis Cluster槽的范围是0~16383。 槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展, 每个节点负责一定数量的槽。
五.搭建redis-cluster槽
搭建集群分为几部
- 准备节点(几匹马儿)
- 节点通信(几匹马儿分配主从)
- 分配槽位给节点(slot分配给马儿)
redis-cluster集群架构
多个服务端,负责读写,彼此通信,redis指定了16384个槽。
多匹马儿,负责运输数据,马儿分配16384个槽位,管理数据。
ruby的脚本自动就把分配槽位这事做了
1.搭建集群
在redis启动文件夹中新建一个文件redis-7000.conf
port 7000 daemonize yes dir "/opt/redis/data" logfile "/opt/redis/logs/7000.log" dbfilename "dump-7000.rdb" cluster-enabled yes # 开启集群模式 cluster-config-file nodes-7000.conf # 集群内部的配置文件 cluster-require-full-coverage no
# redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no
port 7000 daemonize yes dir "/opt/redis/data" logfile "/opt/redis/logs/7000.log" dbfilename "dump-7000.rdb" cluster-enabled yes cluster-config-file nodes-7000.conf
redis支持多实例的功能,我们在单机演示集群搭建,需要6个实例,三个是主节点,三个是从节点,数量为6个节点才能保证高可用的集群。
每个节点仅仅是端口运行的不同,我们批量的生成这些文件!
[root@instance-hrnebyqu redis]# sed 's/7000/7002/g' redis-7000.conf >redis-7002.conf [root@instance-hrnebyqu redis]# sed 's/7000/7003/g' redis-7000.conf >redis-7003.conf [root@instance-hrnebyqu redis]# sed 's/7000/7004/g' redis-7000.conf >redis-7004.conf [root@instance-hrnebyqu redis]# sed 's/7000/7005/g' redis-7000.conf >redis-7005.conf [root@instance-hrnebyqu redis]# sed 's/7000/7005/g' redis-7000.conf >redis-7005.conf
2.确认配置文件无误后开启集群
[root@instance-hrnebyqu redis]# redis-server redis-7000.conf [root@instance-hrnebyqu redis]# redis-server redis-7001.conf [root@instance-hrnebyqu redis]# redis-server redis-7002.conf [root@instance-hrnebyqu redis]# redis-server redis-7003.conf [root@instance-hrnebyqu redis]# redis-server redis-7004.conf [root@instance-hrnebyqu redis]# redis-server redis-7005.conf
注意:这边如果原来有默认6379的扣扣运行的redis进程,需要把他先干掉,再做这一步操作!!!!
3.测试集群是否正常开启
随意进入一个redis
redis-cli -p 7000
4.准备ruby环境
分配redis集群状态,以及槽位分配,互联网企业,豆瓣公司开源的一个工具
- 下载、编译、安装Ruby
- 安装rubygem redis
- 安装redis-trib.rb命令
第一步,安装ruby(这些命令可以放入一个sh脚本文件里)
# 下载ruby wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz # 安装ruby tar -xvf ruby-2.3.1.tar.gz cd ruby-2.3.1/ ./configure --prefix=/opt/ruby/ make && make install # 配置ruby的环境变量 vim /etc/profile 写入如下配置 PATH=$PATH:/opt/ruby/bin
source /etc/profile
# 准备一个ruby命令 # 准备一个gem软件包管理命令 # 拷贝ruby命令到path下/usr/local/ruby cp /opt/ruby/bin/ruby /usr/local/ cp bin/gem /usr/local/bin
第二步:安装ruby gem 包管理工具(相当于在python的中pip的管理工具)
wget http://rubygems.org/downloads/redis-3.3.0.gem gem install -l redis-3.3.0.gem #查看gem有哪些包 gem list -- check redis gem
第三步:安装redis-trib.rb命令
#这个其实不用安装,就在redis的安装包的scr目录下面 #我们这一条命令只是为了把这个命令加到环境变量 cp /opt/redis-4.0.6/src/redis-trib.rb /usr/local/bin/
5.一键开启redis-cluster
redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --replicas # 表示进行身份授权 # 表示每个主节点,只有一个从节点 # 集群会自动分配主从关系 7000、7001、7002为主服务器master 7003、7004、7005为从服务器slave
6.检查集群状态
redis-cli -p 7000 cluster info redis-cli -p 7000 cluster nodes #等同于查看nodes-7000.conf文件节点信息 集群主节点状态 redis-cli -p 7000 cluster nodes | grep master 集群从节点状态 redis-cli -p 7000 cluster nodes | grep slave
[root@instance-hrnebyqu bin]# redis-cli -p cluster info Could not connect to Redis at 127.0.0.1:0: Connection refused [root@instance-hrnebyqu bin]# redis-cli -p 7000 cluster info 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_ping_sent:226 cluster_stats_messages_pong_sent:238 cluster_stats_messages_sent:464 cluster_stats_messages_ping_received:233 cluster_stats_messages_pong_received:226 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:464
[root@instance-hrnebyqu bin]# redis-cli -p 7000 cluster nodes 3a8b74cd2464faf24e833d0d0b189add324e8cc0 127.0.0.1:7000@17000 myself,master - 0 1555927173000 1 connected 0-5460 20b35b67bca63f769fabc69e8de6a8df5427a100 127.0.0.1:7005@17005 slave 3692c24c9bd2cbd772a6ea8b6264033323b6e3ab 0 1555927175000 6 connected ab102dcc0a71e959ff0a9bc074521ff89d4f45f0 127.0.0.1:7004@17004 slave e6cfdec6f4e973f61e08d93984557585bda882c8 0 1555927175412 5 connected e6cfdec6f4e973f61e08d93984557585bda882c8 127.0.0.1:7001@17001 master - 0 1555927174409 2 connected 5461-10922 3692c24c9bd2cbd772a6ea8b6264033323b6e3ab 127.0.0.1:7002@17002 master - 0 1555927173000 3 connected 10923-16383 87532932674692137d96dc7bc9cac2cc891a8cb5 127.0.0.1:7003@17003 slave 3a8b74cd2464faf24e833d0d0b189add324e8cc0 0 1555927173000 4 connected
[root@instance-hrnebyqu bin]# redis-cli -p 7000 cluster nodes |grep master 3a8b74cd2464faf24e833d0d0b189add324e8cc0 127.0.0.1:7000@17000 myself,master - 0 1555927201000 1 connected 0-5460 e6cfdec6f4e973f61e08d93984557585bda882c8 127.0.0.1:7001@17001 master - 0 1555927201463 2 connected 5461-10922 3692c24c9bd2cbd772a6ea8b6264033323b6e3ab 127.0.0.1:7002@17002 master - 0 1555927201000 3 connected 10923-16383 [root@instance-hrnebyqu bin]# [root@instance-hrnebyqu bin]# [root@instance-hrnebyqu bin]# [root@instance-hrnebyqu bin]# [root@instance-hrnebyqu bin]# redis-cli -p 7000 cluster nodes |grep slave 20b35b67bca63f769fabc69e8de6a8df5427a100 127.0.0.1:7005@17005 slave 3692c24c9bd2cbd772a6ea8b6264033323b6e3ab 0 1555927228519 6 connected ab102dcc0a71e959ff0a9bc074521ff89d4f45f0 127.0.0.1:7004@17004 slave e6cfdec6f4e973f61e08d93984557585bda882c8 0 1555927227518 5 connected 87532932674692137d96dc7bc9cac2cc891a8cb5 127.0.0.1:7003@17003 slave 3a8b74cd2464faf24e833d0d0b189add324e8cc0 0 1555927224000 4 connect
7.尝试读写数据
[root@instance-hrnebyqu bin]# redis-cli -p 7000 127.0.0.1:7000> keys * (empty list or set) 127.0.0.1:7000> set name hahhaha (error) MOVED 5798 127.0.0.1:7001 127.0.0.1:7000> set age wocoa OK 127.0.0.1:7000>
注意:记得第一个那么我们在配置redis-cluster设置过name这个key吗?所以我们再写入这个就会失败,但是其他 可以就不会报错!
所以们这边连接的时候应该加上 -c 参数
redis-cli -p 7000 -c
-c 参数表示连接集群
[root@instance-hrnebyqu bin]# redis-cli -p 7000 -c 127.0.0.1:7000> keys * 1) "age" 127.0.0.1:7000> set name haha -> Redirected to slot [5798] located at 127.0.0.1:7001 OK