- 参考视频:https://coding.imooc.com/class/151.html
- 笔记下载地址
- 欢迎star、fork、follow素质三连
单机情况下,对一份特别大的全量数据无法全部保存,只能使用集群模式,将全量数据按照一定规则分配到各个节点上。常用的分区有两个方式:
对比:
分布方式 | 特点 | 典型产品 |
---|---|---|
顺序分布 | 1. 数据分散度容易倾斜 2. 键值业务相关 3. 可顺序访问 4. 支持批量操作 |
1. BigTable 2. HBase |
哈希分布 | 1. 数据分散度高 2. 键值分布和业务无关 3. 无法顺序访问 4. 不支持批量操作 |
1. 一致性哈希Memcache 2. Redis Cluster 3. 其他缓存产品 |
节点取余分区(客户端分片)是最简单的哈希分布:hash(key) % nodes,但是它存在最大的问题是:数据扩容时,可能导致大规模数据发生搬迁。可以使用多倍扩容方式降低数据大规模搬迁(大约有50%的数据会搬迁)。
大规模数据迁移带来最直接的问题时:迁移完成后第一次访问会导致部分数据缓存失效,需要直接到数据库中重新查找数据,并回显给redis缓存,之后再次访问数据时,缓存数据才有效。
对于依靠缓存支撑的系统而言,节点取余法是不能接受的。但是对于一些小应用、可以接受缓存失效直接访问数据库回显的应用,节点取余非常简单。
一致性哈希分区也是客户端分片方式,通过hash(key) % nodes + 顺时针规则找到对应的数据节点,相比于节点取余分区方式,一致性哈希算法特点:
虚拟槽分区是为了解决一致性哈希分区中节点扩容时可能存在负载不均衡的问题。虚拟槽分区特点:
相比于单机redis结构,redis cluster架构中,每个redis节点都负责读、写,并且节点之间是相互通信的,即某个key在由哪个节点负责的消息,各个节点之间相互共享的。当在一个节点上没有查找到对应的key时,该节点会告知其目标节点上查找。但是这种信息共享方式在节点非常多的时候不够高效,更加高效的方式是引入:智能客户端,客户端知道每个节点负责槽的范围,知道某个key在哪个节点上,直接通过智能客户端找到对应的目标节点进行查找。
redis cluster特点:
redis cluster有两种安装方式:原生命令安装和官方工具安装
原生命令安装(有利于理解redis cluster架构)
port 7000
daemonize yes
protected-mode no
pidfile "/var/run/redis-7000.pid"
dir "/opt/soft/redis/data/"
dbfilename "dump-7000.rdb"
logfile "log-7000.log"
cluster-enabled yes
cluster-config-file nodes-7000.conf
# 是否集群中所有节点都提供服务时才认为集群可用
cluster-require-full-coverage no
requirepass tanglei
>> sed "s/7000/7006/g" simple-cnf-7000.conf > simple-cnf-7000.conf
>> sed "s/7000/7001/g" simple-cnf-7000.conf > simple-cnf-7001.conf
>> sed "s/7000/7002/g" simple-cnf-7000.conf > simple-cnf-7002.conf
>> sed "s/7000/7003/g" simple-cnf-7000.conf > simple-cnf-7003.conf
>> sed "s/7000/7004/g" simple-cnf-7000.conf > simple-cnf-7004.conf
>> sed "s/7000/7005/g" simple-cnf-7000.conf > simple-cnf-7005.conf
./redis-server ../config/simple-cnf-7000.conf
./redis-server ../config/simple-cnf-7001.conf
./redis-server ../config/simple-cnf-7002.conf
./redis-server ../config/simple-cnf-7003.conf
./redis-server ../config/simple-cnf-7004.conf
./redis-server ../config/simple-cnf-7005.conf
启动完毕后,才是redis cluster还是处于下线状态:cat /opt/soft/redis/data/notes-7000.conf文件中能看到当前node节点还是只能看到自己:
>> cat nodes-7000.conf
9e9ed81298e81739babb4d36078715da195da3ad :0@0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0
# 也可以使用:
>> ./src/redis-cli -p 7000 -a tanglei cluster nodes
9e9ed81298e81739babb4d36078715da195da3ad :7000@17000 myself,master - 0 0 0 connected
# 还可以使用:
>> ./redis-cli -p 7000 -a tanglei cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:0
cluster_current_epoch:0
cluster_my_epoch:0
cluster_stats_messages_sent:0
cluster_stats_messages_received:0
>> ./redis-cli -p 7000 -a tanglei cluster meet 127.0.0.1 7001
>> ./redis-cli -p 7000 -a tanglei cluster meet 127.0.0.1 7002
>> ./redis-cli -p 7000 -a tanglei cluster meet 127.0.0.1 7003
>> ./redis-cli -p 7000 -a tanglei cluster meet 127.0.0.1 7004
>> ./redis-cli -p 7000 -a tanglei cluster meet 127.0.0.1 7005
# 查看手否握手成功:
>> ./redis-cli -p 7000 -a tanglei cluster info
...
cluster_known_nodes:6
...
# addslots.sh
tart=$1
end=$2
port=$3
for slot in `seq $1 $2`
do
echo "slot:${slot}"
./redis-cli -p ${port} -a tanglei cluster addslots ${slot}
done
# 执行sh脚本进行槽分配
# 给7000端口分配槽:0-5461
>> sh addslots.sh 0 5461 7000
# 给7001端口分配槽:5462-10922
>> sh addslots.sh 5462 10922 7001
# 给7002端口分配槽:10923-16383
>> sh addslots.sh 10923 16383 7002
主从分配基本命令:./redis-cli -p {port} cluster {nodes-id},nodes-id可以通过cluster nodes命令查看到:
# 7003节点成为7000节点的slave节点
./redis-cli -p 7003 -a tanglei cluster replicate 9e9ed81298e81739babb4d36078715da195da3ad # 9e9e...是7000节点的nodes-id
分配完毕后,仍然可以通过cluster nodes命令查看相关主从关系:
>> ./redis-cli -c -p 7000 -a tanglei cluster info
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
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:5
cluster_my_epoch:5
cluster_stats_messages_ping_sent:3111
cluster_stats_messages_pong_sent:3349
cluster_stats_messages_meet_sent:6
cluster_stats_messages_sent:6466
cluster_stats_messages_ping_received:3349
cluster_stats_messages_pong_received:3117
cluster_stats_messages_received:6466
cluster相关命令:
Ruby安装:参考:https://www.cnblogs.com/xuliangxing/p/7146868.html