一、Redis基础
1.SQL与NOSQL
- SQL
- 行存储,二维
- 结构化,Schema
- 表与表之间的关联,Relationship
- SQL语法
- 支持事务,ACID,原子性,一致性,隔离性,持久性
- NOSQL
- 非结构化
- 数据与数据没有关联
- BASE最终一致性
- 海量数据存储,高并发读写
- 支持分布式:数据分片、扩容简单
- 常见的NOSQL
- KV存储、文档存储 MongoDB、列存储 HBase、图存储 Graph Neo4j、对象存储、XML存储…
- Redis特点
- 跨进程,分布式、丰富的数据类型、功能强大、编程语言的支持
2.服务端安装
- 1.下载redis并安装到/usr/local/soft/
- cd /usr/local/soft/
- wget http://download.redis.io/releases/redis-5.0.5.tar.gz
- 2.解压压缩包
- tar -zxvf redis-5.0.5.tar.gz
- 3、安装gcc依赖,redis是C语言编写的,编译需要
- yum install gcc
- 4、编译安装
- cd redis-5.0.5
- make MALLOC=libc
- 将/usr/local/soft/redis-5.0.5/src目录下二进制文件安装到/usr/local/bin
- cd src
- make install
- 5、修改配置文件,/usr/local/soft/redis-5.0.5/redis.conf
- 后台启动:daemonize no 改成 daemonize yes
- bind 127.0.0.1必须改成 bind 0.0.0.0 或注释,否则只能在本机访问
- 如果需要密码访问,取消requirepass的注释,requirepass yourpassword
- 6、使用指定配置文件启动Redis(这个命令建议配置alias)
- /usr/local/soft/redis-5.0.5/src/redis-server /usr/local/soft/redis-5.0.5/redis.conf
- netstat -lnp|grep 6379
- 7、进入客户端(这个命令建议配置alias)
- /usr/local/soft/redis-5.0.5/src/redis-cli
- 8、停止redis(在客户端中)
- redis> shutdown 或
- ps -aux | grep redis 加 kill -9 xxxx
- 9、连接redis服务并设置密码
- redis-cli -h 127.0.0.1 -p 6379
- CONFIG get requirepass
- CONFIG set requirepass “password”
- redis-cli -h 127.0.0.1 -p 6379 -a “password”
二、Redis数据类型
1.String(字符串)
- 一个键最大能存储 512MB
- [EX 多少秒后过期 | PX 多少毫秒后过期] [NX 只有键不存在时才可以操作成功 | XX 只有键存在时才可以操作成功]
- 添加:set name zs / mset name zs age 18 / append name f
- 移除:del name
- 取值:get name / mget name age
- 查看:getrange name 0 -1 / getrange zhangsan 0 2
- 长度:strlen zhangsan
- 整型递增:incr age / incrby age 10
- 整型递减:decr age / decrby age 10
- 应用场景:1.缓存、2.分布式Session、3.set NX EX 分布式锁、4.incr 全局ID、5.incr 计数器、6.incr 限流、7.位操作统计
2.Hash(哈希)
- 是键值(key=>value)对集合,每个hash可以存储40多亿键值对
- 添加:hset user name zs / hmset user name zs age 18
- 移除:hdel user name age
- 取值:hget user name / hmget user name age
- 查看:hkes user / hvals user / hgetall user
- 长度:hlen user
- 判断:hexists user name[判断元素中是否存在某个键]
- 整型递增:hincrby user age 10
- 整型递减:hincrby user age -10
- 与String区别:1.节省空间、2.减少Key冲突、3.减少资源消耗
- 应用场景:
- 1.String能做的他都可以
- 2.购物车
- key:用户id
- field:商品id
- value:商品数量
- 数量+1:hincrby uid fid 1
- 数量-1:hincrby uid fid -1
- 删除:hdel uid fid
- 全选:hgetall uid
- 商品数:hlen uid
3.List(列表)
- 按照插入顺序排序,每个列表可以存储40多亿元素
- 添加:lpush list a b a / rpush list a b a
- 移除:lren list 1 a
- 取值:lpop list / rpop list / blpop list 10
- 查看:lindex list 0 / lrange list 0 -1
- 长度:llen list
- 应用场景
- 1.消息队列
- rpush右边入队,lpop左边出队
- blpop queue 10 [队列无元素时等待指定时间后返回]
4.Set(无序集合)
- 集合内元素的唯一性,第二次插入的元素将被忽略,每个集合可存储40多亿元素
- 添加:sadd myset a b c d e
- 移除:srem myser d e f
- 取值:spop myset 2
- 查看:smembers myset / srandmember myset /
sdiff set1 set2[获取差集(只在第一,不在第二集合的)]
sinter set1 set2[获取交集(两个集合都存在的)]
sunion set1 set2[获取并集(合并后去重)]- 长度:scard myset
- 判断:sismember myset a
- 应用场景
- 1.抽奖
- 通过spop
- 2.点赞、签到、打卡
- 用like1维护这条内容的所有点赞用户
- 点赞:sadd like1 uid1
- 取消点赞:srem like1 uid1
- 是否点赞:sismember like1 uid1
- 点赞所有用户:smembers like1
- 点赞数:scard like1
- 3.商品标签
- 用tags1维护商品的所有标签
- sadd tags1 流畅至极
- sadd tags1 画质清晰
- sadd tags1 真彩清晰
- 4.商品筛选
- sadd brand:huawei huaweimate60rs
- sadd system:harmonyos huaweimate60rs
- sadd dimension:67 huaweimate60rs
- sinter brand:huawei system:harmonyos dimension:67[取交集筛选品牌是华为|鸿蒙操作系统|屏幕在6.0-7.0之间]
- 5.用户关注
- sismember bob:follow me
- sismember me:follow bob
- 都返回1为[相互关注]
- sinter me:follow bob:follow
- 返回的元素为[共同关注]
- sismember {myfollow}:follow leo
- 返回1为[我关注的人也关注了他]
- sdiffstore bob:me bob:follow me:follow
- 取差集并存入bob:me新的set中为[可能认识]
5.ZSet(有序集合,通过分值排序)
- 添加:zadd myset 1 java 2 php 3 python
- 移除:zrem myset php
- 查看:zrange myset 0 -1 withscores
zrevrange myset 0 -1 withscores[大的分值在前]
zrangebyscore myset 2 3 withscores[分值区间的元素]
zrank myset java[查看下标]
zscore myset java[查看分值]- 长度:zcard myset
- 整型递增:zincrby myset 5 java
- 整型递减:zincrby myset -1 java
- 应用场景:
- 排行榜
- zincrby hotnews:20240101 1 n9001
- zrevrange hotnews:20240101 0 15 withscores
- id为n9001的新闻点击加1,并获取今天点击最多的15条
6.Geo(存储地理位置)
- 添加:geoadd citys 121.48 31.22 sh 113.01 28.19 cs 112.95 28.18 yl
- 移除:zrem citys cs
- 查看:geopos citys cs
geodist citys sh cs km[查看两地距离]
georadius citys 113.01 28.19 5 km[查看范围内集合中的元素]
georadiusbymember citys cs 20 km[查看集合内符合范围的元素]
zrange citys 0 -1 withscores[查看集合元素]
zrank citys cs[查看下标]- 长度:zcard citys
7.Hyperloglogs(基数统计)
- 每个HyperLogLog键只需要花费12KB内存,就可以计算接近 2^64 个不同元素的基 数。
- 添加:pfadd log 1 2 3 4 5
- 查看:pfcount log[查看元素个数]
pfmerge nlog log log1[合并元素到新集合]
String字符串 | Hash哈希 | List列表 | Set无序集合 | ZSet有序集合 | Geo | Hyperloglogs | |
---|---|---|---|---|---|---|---|
添加 | set name zs / mset name zs age 18 / append name f | hset user name zs / hmset user name zs age 18 | lpush list a b a / rpush list a b a | sadd myset a b c d e | zadd myset 1 java 2 php 3 python | geoadd citys 121.48 31.22 sh 113.01 28.19 cs 112.95 28.18 yl | pfadd log 1 2 3 4 5 |
移除 | del name | hdel user name age | lren list 1 a | srem myser d e f | zrem myset php | zrem citys cs | |
取值 | get name / mget name age | hget user name / hmget user name age | lpop list / rpop list / blpop list 10 | spop myset 2 | |||
查看 | getrange name 0 -1 / getrange zhangsan 0 2 | hkes user / hvals user / hgetall user | lindex list 0 / lrange list 0 -1 | smembers myset / srandmember myset / sdiff set1 set2 / sinter set1 set2 / sunion set1 set2 | zrange myset 0 -1 withscores / zrevrange myset 0 -1 withscores / zrangebyscore myset 2 3 withscores / zrank myset java / zscore myset java | geopos citys cs / geodist citys sh cs km / georadius citys 113.01 28.19 5 km / georadiusbymember citys cs 20 km / zrange citys 0 -1 withscores / zrank citys cs | pfcount log / pfmerge nlog log log1 |
长度 | strlen name | hlen user | llen list | scard myset | zcard myset | zcard citys | |
判断 | hexists user name | sismember myset a | |||||
整型递增 | incr age / incrby age 10 | hincrby user age 10 | zincrby myset 5 java | ||||
整型递减 | decr age / decrby age 10 | hincrby user age -10 | zincrby myset -1 java |
三、Redis高级功能
1.发布订阅 Pub / Sub
- 订阅频道:subscribe c1 c2
- 订阅相关频道:psubscribe *sport (以sport结尾) / psubscribe sport* (以sport开头)
- 发布消息:publish c1 2673
- 取消订阅:unsubscribe c1
2.事务
- 开启事务:multi
- 执行事务:exec
- 取消事务:discard
- 乐观锁:watch
- 取消锁:unwatch
场景1:事务提交前异常,无法提交事务
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name zs
QUEUED
127.0.0.1:6379> hset name li
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
场景2:事务提交后异常,部分操作成功,因语法造成错误需在开发阶段发现所以Redis默认提交成功。
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name zs
QUEUED
127.0.0.1:6379> hset name a b
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get name
"zs"
127.0.0.1:6379>
场景3:使用乐观锁时,事务未提交时被其他客户端修改,提交事务失败
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR age
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
127.0.0.1:6379> INCRBY age 10
(integer) 28
127.0.0.1:6379>
3.Lua脚本
- 特点:1.批量执行命令、2.原子性、3.操作集合的复用
- Lua脚本语法:eval lua-script key-num [key1 key2 …] [val1 val2 …]
- eval代表执行Lua语言的命令。
- lua-script代表Lua语言脚本内容。
- key-num代表参数中有多少个key。
- redis命令:redis.call(command, key[param1, param2 …])
- command是命令,包括set、get、del等。
- key是被操作的键。
- param1代表给key的参数。
- lua命令:
- 简单命令:eval “redis.call(‘set’,KEYS[1],ARGV[1])” 1 age 18
- IP限流:eval "local num = redis.call(‘incr’,KEYS[1]) if tonumber(num) == 1 then redis.call(‘expire’,KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end " 2 limit192.168.0.1 , 60 3
- lua脚本文件(当lua命令操作较复杂可使用lua脚本文件):
- 准备:iplimit.lua文件,内容为:local num = redis.call(‘incr’,KEYS[1]) if tonumber(num) == 1 then redis.call(‘expire’,KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end
- 执行:redis-cli --eval iplimit.lua limit192.168.0.1 , 60 3 #当该IP访问连续3次后返回0,不允许再次操作
- 缓存lua脚本:
- script load “local num = redis.call(‘incr’,KEYS[1]) if tonumber(num) == 1 then redis.call(‘expire’,KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end”
- evalsha “23caf9145c08d9056813bf06bdbe06435bdab856” 2 limit192.168.0.1 , 60 3
- 脚本超时未修改值时:script kill
- 脚本超时有修改值时:shutdown nosava
4.数据淘汰与内存回收
过期策略
(针对设置了过期时间数据的清除机制):redis采用的是后两种过期策略
。
- 定时过期:到了key过期时间,立即删除。
惰性过期
:key被访问的时候才判断是否过期,过期则删除。定期过期
:每隔一段时间,清除一定数量过期的key。淘汰策略
(在内存使用超过最大允许值时采取的一种保护策略):
- Volatile 针对设置了过期时间的key / Allkeys 针对所有key。
LRU
最近最少使用,基于数据的最近访问时间来决定。LFU
最不经常使用,基于数据的访问频率来决定。RANDOM
随机选择一些过期的key把它删除释放内存。TTL
优先删除最近即将要过期的key。- 例如:
- volatile-lru
- allkeys-lru
- volatile-lfu
- allkeys-lfu
- volatile-random
- allkeys-random
- volatile-ttl
- noeviction
#redis默认没有淘汰策略
。- 修改可通过conf中maxmemory-policy属性调整。
5.数据持久化
RDB:redis默认持久化方案
。
自动触发
:shutdown触发
或flushall触发
或配置规则触发
。
- 配置规则触发:
conf文件中SNAPSHOTTING
save 900 1 #900秒只要有1个被修改就会触发内存到RDB文件的写入
save 300 10 #900秒只要有1个被修改就会触发内存到RDB文件的写入
save 60 10000 #900秒只要有1个被修改就会触发内存到RDB文件的写入- RDB相关配置:
- rdbcompression yes #采用LZF算法对RDB文件压缩
- rdbchecksum yes #采用CRC64对RDB的完整性校验
手动触发
:
save
:生成快照时会阻塞redis服务。bgsave
:会异步生成快照不会阻塞服务。- 特点:文件紧凑、不影响主进程、恢复大数据集时速度比较快、同步频率。
AOF:redis可同步开启AOF,记录的是执行的命令
。
开启
:conf文件中设置 appendonly yes #开启AOF,`首次使用时需手动重写bgrewriteaof,默认先加载AOF文件。写入时机
:
- appendfsync always #每个写命令执行后,都会立即同步AOF文件到磁盘
- appendfsync everysec
#默认每秒同步一次 AOF 文件到磁盘
- appendfsync no #由操作系统决定何时同步AOF文件到磁盘
AOF文件过大时会触发文件重写
:
手动触发
:bgrewriteaof #AOF重写命令。自动触发
:
- auto-aof-rewrite-percentage 100 #当AOF文件的大小比上一次AOF重写后的大小大指定的百分比时,将触发 AOF 重写过程
- auto-aof-rewrite-min-size 64mb #只有当AOF文件的大小大于这个值时,才会触发AOF重写
- 特点:多种同步频率、文件较大、可靠性较高、性能较高但并发性能不如RDB。
6.pipeline管道技术,用于批量操作
四、Redis集群与分布式
1.什么情况下需要集群
- 1.需要提升性能的情况
- 2.需要水平扩容的情况
- 3.防止单点故障的情况
2.主从复制配置
- 192.168.0.1 主节点、192.168.0.2 从节点、192.168.0.3 从节点
- 主从复制方式:
- 配置文件:slaveof 192.168.0.1 6379
- 命令参数:slaveof 192.168.0.1 6379
- 启动参数:redis-server --slaveof 192.168.0.1 6379
- 查看主从服务器的复制信息:info replication
- 断开从节点:slaveof no one
3.主从复制原理
- 1.
连接阶段
:从节点有个定时任务会检查有没有主节点要去连接,发现有的话就回去主节点建立socket连接。- 2.
数据同步阶段
:
- 1.主节点通过bgsave命令生成RDB快照文件。
- 2.从节点会先清空自己后全量加载主节点数据。
- 3.针对生成快照后的写入命令会缓存在内存里面,当从节点全量加载完数据时,会把缓存的命令再复制给从节点。
- 3.
命令传播
:后续通过异步的复制同步到从节点。
- 存在的问题:网络问题导致部分命令未同步到从节点,等恢复连接后时候需要重新执行未同步的数据,
redis是通过slave_repl_offset偏移量实现增量复制
。
4.哨兵Sentinel模式配置
- 针对主从复制的不足,产生的高可用哨兵模式。
- 1.但各节点数据量大时,同步比较耗时。
- 2.主节点挂掉了需要手动切换主从。
- 哨兵配置:
- 注意:开启哨兵模式,至少需要3个Sentinel实例(奇数个,否则无法选举Leader)。
- IP地址:节点角色&端口
192.168.0.1 Master:6379 / Sentinel : 26379
192.168.0.2 Slave : 6379 / Sentinel : 26379
192.168.0.3 Slave : 6379 / Sentinel : 26379- 默认根目录有sentinel.conf配置文件,备份后修改内容,三台机器相同。
daemonize yes
port 26379
protected-mode no
dir “/usr/local/soft/redis-5.0.5/sentinel-tmp”
sentinel monitorredis-master
192.168.0.1 6379 2
sentinel down-after-milliseconds redis-master 30000
sentinel failover-timeout redis-master 180000
sentinel parallel-syncs redis-master 1
- #
down-after-milliseconds
作用:
- 宕机多久才会被哨兵主观认为下线
- #
failover-timeout
作用:
- 1.Sentinel对一个主节点进行故障转移失败,那么下次再对该主节点进行故障转移的起始时间将是failover-timeout的2倍。
- 2.Sentinel节点向选出的从节点执行slaveof no one命令一直失败当这个过程超过failover-timeout时,故障转移会被判定为失败。
- 3.Sentinel节点会执行info命令来确认选出的从节点是否确实已经晋升为主节点。如果这个确认过程执行时间超过了failover-timeout,则故障转移也会被判定为失败。
- 4.即命令其余从节点复制新的主节点的过程中,如果执行时间超过了failover-timeout(不包含复制时间),则故障转移同样会失败。
- #
parallel-syncs
作用:
- 限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数。
- 在3台机器上分别启动Redis和Sentinel:
cd /usr/local/soft/redis-5.0.5/src
./redis-server …/redis.conf
./redis-sentinel …/sentinel.conf
哨兵另一种启动方式:
./redis-server …/sentinel.conf --sentinel- 在3台机器上查看集群状态:
info replication
5.哨兵Sentinel原理
服务下线
- 哨兵给master节点发起ping超过down-after-milliseconds时间未回复,此时是
主观下线
。- 这时哨兵发起询问,如果一半以上其他哨兵节点都告诉我master节点下线了,此时是
客观下线
。
Leader选举
(Raft-共识算法,先到先得,少数服从多数)
- 1.
故障转移过程
:
- 节点1挂掉
- 节点2先slaveof no one 成为master节点
- 节点3再slaveof xipx xportx
- 此时节点2成为新的master节点
- 2.
影响选举因素
:
断开连接的时长
越短,概率越高优先级越高
,概率越高(conf可配置,数值越小优先级越高,replica-priority 100)offset 复制的数据越多
(数据越完整),概率越高进程id最小的
,概率越高
6.Redis分片
客户端分片
- Jedis已经实现好了客户端分片。
- 缺点:不能动态选择,客户端代码重复。
JedisPoolConfig poolConfig = new JedisPoolConfig();
JedisShardInfo info1 = new JedisShardInfo('192.168.0.1',6379)
JedisShardInfo info2 = new JedisShardInfo('192.168.0.2',6379)
List<JedisShardInfo> infolist = Arrays.asList(info1, info2);
ShardedJedisPool jedisPool = new ShardedJedisPoo(poolConfig, infoList);
ShardedJedis jedis = jedisPool.getResource();
for(int i=0;i<100;i++){
jedis.set("k"+i,""+i);
}
for(int i=0;i<100;i++){
Client client= jedis.getShard("k"+i,""+i).getClient();
System.out.println(jedis.get("k"+i)+"-"+client.getHost()+"-"+client.getPort())
}
代理分片
- Twemproxy
- 缺点:
- Twemproxy组件出现问题时,不能实现自动转移,需要借助其他组件如LVS。
- 扩容缩容时需要修改Twemproxy的配置,并且需要重新分布数据,不能实现平滑的扩容缩容。
- Codis
- go语言编写的高新能redis集群解决方案。
- 特点:
- 平滑扩容:Codis支持平滑扩容,可以在不停机的情况下添加新的Redis节点,并通过数据迁移保证数据的完整性和一致性。
- 对客户端透明:对于上层应用来说,连接到Codis Proxy和连接原生的Redis Server没有明显的区别。上层应用可以像使用单机的Redis一样使用Codis,而无需关心底层的分布式处理逻辑。
服务端分片
Cluster
- 数据分片需要解决几个关键的问题:
- 数据怎么均匀的分片,分片算法的问题
- 客户端怎么访问到相应的节点拿到数据,路由的问题
- 重新分片过程中,有节点增减的情况,怎么保证服务正常的提供给客户端访问,故障转移的问题。
配置过程:为了节省机器,我们直接把6个Redis实例安装在同一台机器上(3主3从),只是使用不同的端口号。
1.准备分片文件夹,并将redis.conf文件复制到7291中
cd /usr/local/soft/redis-5.0.5
mkdir redis-cluster
cd redis-cluster
mkdir 7291 7292 7293 7294 7295 7296
cp /usr/local/soft/redis-5.0.5/redis.conf /usr/local/soft/redis-5.0.5/redis-cluster/7291
2.修改redis.conf相关信息
cd redis-cluster/7291/
vim redis.conf
======redis.conf begin======
port 7291
daemonize yes
protected-mode no
dir /usr/local/soft/redis-5.0.5/redis-cluster/7291/
cluster-enabled yes
cluster-config-file nodes-7291.conf
cluster-node-timeout 5000
appendonly yes
pidfile /var/run/redis_7291.pid
======redis.conf end======
3.将修改后的文件复制到其他文件夹,并批量替换端口信息
cp redis.conf ../7292
cp redis.conf ../7293
cp redis.conf ../7294
cp redis.conf ../7295
cp redis.conf ../7296
cd /usr/local/soft/redis-5.0.5/redis-cluster
sed -i 's/7291/7292/g' 7292/redis.conf
sed -i 's/7291/7293/g' 7293/redis.conf
sed -i 's/7291/7294/g' 7294/redis.conf
sed -i 's/7291/7295/g' 7295/redis.conf
sed -i 's/7291/7296/g' 7296/redis.conf
4.启动6个Redis节点并查看是否启动成功
cd /usr/local/soft/redis-5.0.5/
./src/redis-server redis-cluster/7291/redis.conf
./src/redis-server redis-cluster/7292/redis.conf
./src/redis-server redis-cluster/7293/redis.conf
./src/redis-server redis-cluster/7294/redis.conf
./src/redis-server redis-cluster/7295/redis.conf
./src/redis-server redis-cluster/7296/redis.conf
ps -ef|grep redis
5.创建集群(Redis会给出一个预计的方案,对6个节点分配3主3从,如果认为没有问题,输入yes确认)
cd /usr/local/soft/redis-5.0.5/src/
redis-cli --cluster create 192.168.43.101:7291 192.168.43.101:7292 192.168.43.101:7293 192.168.43.101:7294 192.168.43.101:7295 192.168.43.101:7296 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.43.101:7295 to 192.168.43.101:7291
Adding replica 192.168.43.101:7296 to 192.168.43.101:7292
Adding replica 192.168.43.101:7294 to 192.168.43.101:7293
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: c39dbaf415d257670edbda235b90f607249eafcd 192.168.43.101:7291
slots:[0-5460] (5461 slots) master
M: 374de01cc0d51c556c89ea81e0eb24a061f3a419 192.168.43.101:7292
slots:[5461-10922] (5462 slots) master
M: 9548a0badca30a36c861e1554a7acc0e18473b7e 192.168.43.101:7293
slots:[10923-16383] (5461 slots) master
S: 9ddd22b5a039fa3ab0357fe796d83bbc0ba11886 192.168.43.101:7294
replicates 9548a0badca30a36c861e1554a7acc0e18473b7e
S: 587c711a1968ecff328fe200b550d1523741408d 192.168.43.101:7295
replicates c39dbaf415d257670edbda235b90f607249eafcd
S: 1185ac994f095ea2cd8a2ab4dabb05f2413742e0 192.168.43.101:7296
replicates 374de01cc0d51c556c89ea81e0eb24a061f3a419
Can I set the above configuration? (type 'yes' to accept): yes
- 注意看slot的分布:
- 7291 [0-5460] (5461 slots)
- 7292 [5461-10922] (5462 slots)
- 7293 [10923-16383] (5461 slots)
6.集群创建完成
>>> 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.43.101:7291)
M: c39dbaf415d257670edbda235b90f607249eafcd 192.168.43.101:7291
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 374de01cc0d51c556c89ea81e0eb24a061f3a419 192.168.43.101:7292
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 1185ac994f095ea2cd8a2ab4dabb05f2413742e0 192.168.43.101:7296
slots: (0 slots) slave
replicates 374de01cc0d51c556c89ea81e0eb24a061f3a419
M: 9548a0badca30a36c861e1554a7acc0e18473b7e 192.168.43.101:7293
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 9ddd22b5a039fa3ab0357fe796d83bbc0ba11886 192.168.43.101:7294
slots: (0 slots) slave
replicates 9548a0badca30a36c861e1554a7acc0e18473b7e
S: 587c711a1968ecff328fe200b550d1523741408d 192.168.43.101:7295
slots: (0 slots) slave
replicates c39dbaf415d257670edbda235b90f607249eafcd
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
7.查看是否可以连接到redis客户端
redis-cli -p 7291
redis-cli -p 7292
redis-cli -p 7293
8.编写批量写入脚本,并给权限执行脚本文件
cd /usr/local/soft/redis-5.0.5/redis-cluster/
vim setkey.sh
======setkey.sh begin======
#!/bin/bash
for ((i=0;i<20000;i++))
do
echo -en "helloworld" | redis-cli -h 192.168.43.101 -p 7291 -c -x set name$i >>redis.log
done
======setkey.sh end======
chmod +x setkey.sh
./setkey.sh
9.执行完后,连接到redis 7291 7292 7293客户端查看数据分布
[root@master redis-cluster]# redis-cli -p 7291
127.0.0.1:7291> DBSIZE
(integer) 6652
127.0.0.1:7291> exit
[root@master redis-cluster]# redis-cli -p 7292
127.0.0.1:7292> DBSIZE
(integer) 6683
127.0.0.1:7292> exit
[root@master redis-cluster]# redis-cli -p 7293
127.0.0.1:7293> DBSIZE
(integer) 6665
127.0.0.1:7293> exit
[root@master redis-cluster]#
如何选择分片方式?
选择哪种分片方式取决于具体的应用场景和需求。
客户端分片可以更好地控制数据的分布和查询,但需要客户端具备一定的逻辑处理能力;
代理分片可以简化客户端的实现,但需要额外的代理服务器和配置;
Redis Cluster分片则提供了去中心化、高可用、自动扩展等特性,是一种比较完整的分布式解决方案。
切换用户[su - root]
重启[reboot]
[查看6379端口]netstat -lnp|grep 6379
[查看pid]ps -aux|grep redis
[查看pid]ps -ef|grep redis
cluster info :打印集群的信息
cluster nodes :列出集群当前已知的所有节点(node),以及这些节点的相关信息。
cluster meet :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> :从集群中移除 node_id 指定的节点(保证空槽道)。
cluster replicate <node_id> :将当前节点设置为 node_id 指定的节点的从节点。
cluster saveconfig :将节点的配置文件保存到硬盘里面。
槽slot命令
cluster addslots [slot …] :将一个或多个槽(slot)指派(assign)给当前节点。
cluster delslots [slot …] :移除一个或多个槽对当前节点的指派。
cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
cluster setslot node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
cluster setslot migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
cluster setslot importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
cluster setslot stable :取消对槽 slot 的导入(import)或者迁移(migrate)。
键命令
cluster keyslot :计算键 key 应该被放置在哪个槽上。
cluster countkeysinslot :返回槽 slot 目前包含的键值对数量。
cluster getkeysinslot :返回 count 个 slot 槽中的键
虚拟机安装:https://blog.csdn.net/weixin_74195551/article/details/127288338
虚拟机许可证:JU090-6039P-08409-8J0QH-2YR7F
阿里云CentOS7下载:https://mirrors.aliyun.com/centos/7/isos/x86_64/?spm=a2c6h.25603864.0.0.378f4511VEVve8
CentOS7安装:https://blog.csdn.net/weixin_43849575/article/details/102996790
NAT模式配置:https://blog.csdn.net/m0_49797779/article/details/122290800
CentOS7单机安装Redis Cluster(3主3从):https://gper.club/articles/7e7e7f7ff7g5egc7g6d