Redis

一、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有序集合GeoHyperloglogs
添加set name zs / mset name zs age 18 / append name fhset user name zs / hmset user name zs age 18lpush list a b a / rpush list a b asadd myset a b c d ezadd myset 1 java 2 php 3 pythongeoadd citys 121.48 31.22 sh 113.01 28.19 cs 112.95 28.18 ylpfadd log 1 2 3 4 5
移除del namehdel user name agelren list 1 asrem myser d e fzrem myset phpzrem citys cs
取值get name / mget name agehget user name / hmget user name agelpop list / rpop list / blpop list 10spop myset 2
查看getrange name 0 -1 / getrange zhangsan 0 2hkes user / hvals user / hgetall userlindex list 0 / lrange list 0 -1smembers myset / srandmember myset / sdiff set1 set2 / sinter set1 set2 / sunion set1 set2zrange myset 0 -1 withscores / zrevrange myset 0 -1 withscores / zrangebyscore myset 2 3 withscores / zrank myset java / zscore myset javageopos 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 cspfcount log / pfmerge nlog log log1
长度strlen namehlen userllen listscard mysetzcard mysetzcard citys
判断hexists user namesismember myset a
整型递增incr age / incrby age 10hincrby user age 10zincrby myset 5 java
整型递减decr age / decrby age 10hincrby user age -10zincrby 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 monitor redis-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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值