-
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
-
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
-
redis优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
-
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
-
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
-
select 0~15 指定数据库
-
redis keys命令:
- DEL key – 当key存在是删除key
- EXISTS key – 检查给定key是否存在
- EXPIRE key seconds – 为给定key设置过期时间,以秒记
- PERSIST key – 移除key的过期时间,key将持久保存
- TTL key – 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
- RENAME key newkey – 修改key的名称
- keys na* --模糊查询key值
-
redis字符串命令:
- SET key value – 设置指定 key 的值。
- GET key – 获取指定 key 的值。
- GETRANGE key start end – 返回 key 中字符串值的子字符。
- GETSET key value – 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
- MGET key1 [key2…] – 获取所有(一个或多个)给定 key 的值。
- SETNX key value – 只有在 key 不存在时设置 key 的值。
- SETRANGE key offset value – 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
- MSET key value [key value …] – 同时设置一个或多个 key-value 对。
- MSETNX key value [key value …] – 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
- INCR key – 将 key 中储存的数字值增一。
- INCRBY key increment – 将 key 所储存的值加上给定的增量值(increment)。
- DECR key – 将 key 中储存的数字值减一。
- INCRBYFLOAT key increment – 将 key 所储存的值加上给定的浮点增量值(increment)。
- APPEND key value – 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
-
Redis hash : Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
-
Redis hash 命令:
-
HSET key field value – 将哈希表 key 中的字段 field 的值设为 value 。
-
HSETNX key field value – 只有在字段 field 不存在时,设置哈希表字段的值。
-
HMSET key field1 value1 [field2 value2 ] – 同时将多个 field-value (域-值)对设置到哈希表 key 中。
-
HDEL key field1 [field2] – 删除一个或多个哈希表字段。
-
HEXISTS key field – 查看哈希表 key 中,指定的字段是否存在。
-
HGET key field – 获取存储在哈希表中指定字段的值。
-
HGETALL key – 获取在哈希表中指定 key 的所有字段和值。
-
HKEYS key – 获取所有哈希表中的字段。
-
HMGET key field1 [field2] – 获取所有给定字段的值。
-
HLEN key – 获取哈希表中字段的数量。
-
Redis 列表(List): Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
-
Redis 列表命令
- LPUSH key value1 [value2] – 将一个或多个值插入到列表头部
- RPUSH key value1 [value2] – 在列表中添加一个或多个值
- LPUSHX key value – 将一个值插入到已存在的列表头部
- RPUSHX key value – 为已存在的列表添加值
- LINSERT key BEFORE|AFTER pivot value – 在列表的元素前或者后插入元素
- LINDEX key index – 通过索引获取列表中的元素
- LLEN key – 获取列表长度
- LRANGE key start stop – 获取列表指定范围内的元素
- LREM key count value – 移除列表元素
- RPOP key – 移除列表的最后一个元素,返回值为移除的元素
- LPOP key – 移出并获取列表的第一个元素
- RPOPLPUSH source destination – 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
- LSET key index value – 通过索引设置列表元素的值
- LTRIM key start stop – 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
-
Redis 集合(Set):Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
-
redis集合命令
- SADD key member1 [member2] – 向集合添加一个或多个成员
- SCARD key – 获取集合的成员数
- SDIFF key1 [key2] – 返回给定所有集合的差集
- SDIFFSTORE destination key1 [key2] – 返回给定所有集合的差集并存储在 destination 中
- SINTER key1 [key2] – 返回给定所有集合的交集
- SINTERSTORE destination key1 [key2] – 返回给定所有集合的交集并存储在 destination 中
- SISMEMBER key member – 判断 member 元素是否是集合 key 的成员
- SMEMBERS key – 返回集合中的所有成员
- SMOVE source destination member – 将 member 元素从 source 集合移动到 destination 集合
- SPOP key – 移除并返回集合中的一个随机元素
- SRANDMEMBER key [count] – 返回集合中一个或多个随机数
- SREM key member1 [member2] – 移除集合中一个或多个成员
- SUNION key1 [key2] – 返回所有给定集合的并集
- SUNIONSTORE destination key1 [key2] – 所有给定集合的并集存储在 destination 集合中
- SSCAN key cursor [MATCH pattern]-[ COUNT coun] – 迭代集合中的元素
-
Redis 有序集合(sorted set):Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
-
Redis 有序集合命令:
- ZADD key score1 member1 [score2 member2] – 向有序集合添加一个或多个成员,或者更新已存在成员的分数
- ZCARD key – 获取有序集合的成员数
- ZCOUNT key min max – 计算在有序集合中指定区间分数的成员数
- ZINCRBY key increment member – 有序集合中对指定成员的分数加上增量 increment
- ZINTERSTORE destination numkeys key [key …] – 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
- ZLEXCOUNT key min max – 在有序集合中计算指定字典区间内成员数量
- ZRANGE key start stop [WITHSCORES] – 通过索引区间返回有序集合成指定区间内的成员
- ZRANGEBYLEX key min max [LIMIT offset count] – 通过字典区间返回有序集合的成员
- ZRANK key member – 返回有序集合中指定成员的索引
- ZREM key member [member …] – 移除有序集合中的一个或多个成员
- ZREMRANGEBYLEX key min max – 移除有序集合中给定的字典区间的所有成员
- ZREMRANGEBYRANK key start stop – 移除有序集合中给定的排名区间的所有成员
- ZREMRANGEBYSCORE key min max – 移除有序集合中给定的分数区间的所有成员
- ZSCORE key member – 返回有序集中,成员的分数值
- ZUNIONSTORE destination numkeys key [key …] – 计算给定的一个或多个有序集的并集,并存储在新的 key 中
- ZSCAN key cursor [MATCH pattern]-[ COUNT coun] – 迭代有序集合中的元素(包括元素成员和元素分值)
-
flushdb 删除当前选择的数据库中所有的key
-
flushall 删除所有数据库中的所有key
-
Redis HyperLogLog: Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
-
什么是基数:比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。
-
Redis HyperLogLog 命令:
- PFADD key element [element …] – 添加指定元素到 HyperLogLog 中
- PFCOUNT key [key …] – 返回给定 HyperLogLog 的基数估算值
- PFMERGE destkey sourcekey [sourcekey …] – 将多个 HyperLogLog 合并为一个 HyperLogLog
-
Redis 发布订阅:Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis 客户端可以订阅任意数量的频道。
-
Redis 发布订阅命令:
- PSUBSCRIBE pattern [pattern …] – 订阅一个或多个符合给定模式的频道
- PUBSUB subcommand [argument [argument …]] – 查看订阅与发布系统状态
- PUBLISH channel message – 将信息发送到指定的频道
- PUNSUBSCRIBE [pattern [pattern …]] – 退订所有给定模式的频道。
- SUBSCRIBE channel [channel …] – 订阅给定的一个或多个频道的信息。
- UNSUBSCRIBE [channel [channel …]] – 指退订给定的频道。
-
Redis 事务: MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令。将多个命令请求打包,然后一次性、按顺序去执行,在事物执行期间服务器不会终端事物而改去执行其他客户端请求命令,要等事物中的所有命令执行完毕,才去执行其他客户端的请求命令。
-
在开启事物之前先锁定值,当值发生变化的时候,后续的事物将会提交失败
watch ticket
MULTI
decrby ticket 1
…
EXEC
-
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
-
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
-
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
-
Redis 事务命令
- DISCARD – 取消事务,放弃执行事务块内的所有命令。
- EXEC – 执行所有事务块内的命令
- MULTI – 标记一个事务块的开始。
- UNWATCH – 取消 WATCH 命令对所有 key 的监视
-
Redis 连接:Redis 连接命令主要是用于连接 redis 服务
-
Redis 连接命令
- AUTH password – 验证密码是否正确
- ECHO message – 打印字符串
- PING – 查看服务是否运行
- QUIT – 关闭当前连接
- SELECT index – 切换到指定的数据库
-
Redis 数据备份: SAVE 命令用于创建当前数据库的备份,该命令将在 redis 安装目录中创建dump.rdb文件。
-
Redis 数据恢复:如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。获取 redis 目录可以使用 CONFIG 命令,如下所示:
CONFIG GET dir
以上命令 CONFIG GET dir 输出的 redis 安装目录为 /usr/local/redis/bin
-
创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行
-
Redis 安全:我们可以通过 redis 的配置文件设置密码参数,这样客户端连接到 redis 服务就需要密码验证,这样可以让你的 redis 服务更安全。
- CONFIG get requirepass – 查看是否设置了密码验证
- CONFIG set requirepass “runoob” – 设置密码
-
Redis 管道技术: Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:
- 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
- 服务端处理命令,并将结果返回给客户端。
-
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
-
持久化: RDB和AOF
-
RDB(快照): 相当于定期给内存中的数据拍一张照片,保存到硬盘中。
-
RDB文件的创建,可通过save或者bgsave
- 当save命令执行时,Redis服务器会被阻塞,此时客户端发送的所有请求都会被拒绝,需等待save命令执行完毕,才能接收客户端请求。
- bgsave是由子进程执行,所以Redis服务是非阻塞的,可以接收客户端的请求,但是在bgsave命令执行期间,当再执行save、bgsave或bgrewriteaof三个命令时会有所不同,如执行save或bgsave直接拒绝,如执行bgrewriteaof会延时在bgsave完毕之后才执行。
-
自动间隔性保存,可通过以下配置完成:
在满足以下3个条件时,bgsave命令就会被执行,生成dump.rdb文件:
-
save 900 #900秒内,如果有一个key的value发生变化,则执行RDB
-
save 300 #300秒内,如果有10个key的value发生变化,则执行RDB
-
save 60 #60秒内,如果有10000个key的value发生变化,则执行RDB
缺点:在两次RDB之间,数据肯定会丢失。
-
-
RDB默认开启,可以在redis.conf配置文件中修改上述策略
save 900 1
save 300 10
save 60 10000 -
AOF(日志),默认关闭需修改配置文件redis.conf开启,对服务器压力比较大:
appendonly yes 开启AOF
appendfilename “appendonly.aof” AOF产生的日志文件
-
AOF产生的策略
appendfsync always 每个操作
appendfsync everysec 每秒
appendfsync no -
AOF日志的重写,当AOF超过64M时,发生重写。
-
Redis读写分离,在Redis中可以通过slaveof命令或设置conf配置文件中的slaveof选项,实现主从复制,读写分离。
-
体系结构和原理
-
星型结构
优点:效率高
缺点:HA实现麻烦
1)选举其中的一个从节点为Master
2) 其他从节点需要重新连接到新的Master
-
线型结构
优点:HA实现简单
1)把紧邻的Slave变为Master
缺点:
效率低:
-
-
星型结构的实现方式
-
在主节点的配置文件上面关闭RDB和AOF
bind 0.0.0.0 # save 900 1 # save 300 10 # save 60 10000 appendonly no
-
修改从节点1的配置文件
bind 0.0.0.0 port 6380 replicaof 192.168.18.177 6379 dbfilename dump_6380.rdb appendfilename "appendonly_6380.aof"
-
修改从节点2的配置文件
bind 0.0.0.0 port 6381 replicaof 192.168.18.177 6379 dbfilename dump_6381.rdb appendfilename "appendonly_6381.aof"
-
-
连接指定端口号的redis: redis-cli -p 6379
-
只能在主节点上面写入数据,不能再从节点上面写入数据,报错信息为
(error) READONLY You can't write against a read only replica.
-
哨兵机制
Sentinel: (哨岗、哨兵)是Redis高可用解决方案,由一个或多个Sentinel组成,在redis中要实现哨兵机制,redis必须在2.4+版本。
Sentinel哨兵 —> 主服务器下线 ----> 故障迁移(重新选取主服务器) ----> 原主服务器启动后将降级为从服务器
哨兵机制会监视redis集群中的所有节点,当检测到主服务器下线时,哨兵会在所有的从节点中重新选取一个主节点,原主服务器恢复后,将降级为从服务器,并从新的主节点上面复制数据。
-
哨兵配置,修改sentinel.conf
sentinel monitor mymaster 192.168.18.177 6379 1 #主节点ip 主节点端口号 哨兵个数 sentinel auth-pass <master-name> <password> # 设置哨兵连接主节点时的用户名和密码 sentinel down-after-milliseconds mymaster 30000 #多少秒内没有收到主节点的心跳,哨兵就认为主节点挂了 sentinel parallel-syncs mymaster 1 #选举新的主节点后,可以同时连接其他从节点个数,不能太大 sentinel failover-timeout mymaster 180000 #失败切换时,允许的最大时间
-
启动哨兵
redis-sentinel sentinel.conf
启动后日志为
1538:X 15 May 2019 15:45:17.882 # +monitor master mymaster 192.168.18.177 6379 quorum 1 1538:X 15 May 2019 15:45:17.883 * +slave slave 192.168.18.177:6380 192.168.18.177 6380 @ mymaster 192.168.18.177 6379 1538:X 15 May 2019 15:45:17.884 * +slave slave 192.168.18.177:6381 192.168.18.177 6381 @ mymaster 192.168.18.177 6379
-
查看节点信息: info replication
主节点:
# Replication role:master connected_slaves:2 slave0:ip=192.168.18.177,port=6380,state=online,offset=57336,lag=1 slave1:ip=192.168.18.177,port=6381,state=online,offset=57336,lag=1 master_replid:a317eba3b8ffa1ada4d8ae59e7291a00c945d1b9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:57336 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:57336
从节点:
# Replication role:slave master_host:192.168.18.177 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:48002 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:a317eba3b8ffa1ada4d8ae59e7291a00c945d1b9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:48002 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:48002
-
Spring Boot连接哨兵的配置文件
spring: redis: # host: 192.168.18.177 #连接单节点redis # password: jfpt_common # port: 6381 database: 0 #数据库0 timeout: 5000 sentinel: #Redis哨兵(HA) master: mymaster nodes: 192.168.18.177:26379 jedis: pool: max-idle: 100 min-idle: 1 max-active: 1000 max-wait: -1
-
Spring Boot使用redis集群的代码
@Autowired private StringRedisTemplate stringRedisTemplate; @RequestMapping("set") public String setValue(String key, String value){ stringRedisTemplate.opsForValue().set(key, value); String newValue = stringRedisTemplate.opsForValue().get(key); return newValue; }
-
Redis集群:Redis集群是Redis3.0版本开始提供的分布式数据库方案,通过分片(sharding)进行数据共享,并提供复制和故障迁移的功能,集群中可以有多个master。
-
槽指派:Redis集群通过分片的方式来保存数据库中的键值,集群中的整个redis数据库别分为16384个槽(slot),数据库中的每个键都数据16384个槽中的其中一个,集群中的每个节点可处理为16384个槽。将Key值进行CRC16计算,得到的数值对16384取模
-
Redis集群的配置
-
复制一个全新的redis.conf配置文件
-
新建cluster 文件夹: mkdir cluster
-
在cluster下新建文件夹: mkdir -p 7001 7002 7003 7004 7005 7006
-
修改配置文件
port 7001 # 节点端口号 daemonize yes # bind 0.0.0.0 #绑定机器IP dir /usr/redis/cluster/7001/ #数据文件存放位置 pidfile /var/run/redis_7001.pid #7001要和port对应 cluster-enabled yes #启动集群模式 cluster-config-file nodes-7001.conf #7001要和port对应 cluster-node-timeout 10000 #拦截超时等待时间 appendonly yes appendfilename "appendonly_7001.aof"
-
将上面的文件分别复制到 cluster/7001 到 cluster/7006,并将使用对应的文件夹的数字替换配置文件中的内容:
:%s /7001/7002
-
分别启动六个redis服务
redis-server ./cluster/7001/redis.conf
-
此时往redis中写入数据时会报如下的错误,原因是没有安装ruby
(error) CLUSTERDOWN Hash slot not served
-
安装ruby
yum install ruby yum install rubygems gem install redis
-
执行上面第三步时会报如下的错误
ERROR: Error installing redis: redis requires Ruby version >= 2.2.2.
-
继续执行下面的命令
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB curl -sSL https://get.rvm.io | bash -s stable find / -name rvm -print source /usr/local/rvm/scripts/rvm rvm list known rvm install 2.4.1 rvm use 2.4.1 rvm use 2.4.1 --default rvm remove 2.3.4 ruby --version gem install redis
链接为:http://www.cnblogs.com/Patrickliu/p/8454579.html
-
创建集群
./redis-cli --cluster create --cluster-replicas 1 192.168.18.177:7001 192.168.18.177:7002 192.168.18.177:7003 192.168.18.177:7004 192.168.18.177:7005 192.168.18.177:7006
–cluster-replicas 1 表示主从复制比例为1:1,即一个主节点对应一个从节点,在redis集群中默认有16383个solt,默认平均分配
-
输出的内容为:
M: cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 192.168.18.177:7001 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 3e88c6431b67db01a3f37cb73668edd36003b4cf 192.168.18.177:7006 slots: (0 slots) slave replicates 5515163a16503a5892e0d0fc14a5b292d76216c0 S: 4603f8973e3f641ae839872a5b3e963e19a7de07 192.168.18.177:7005 slots: (0 slots) slave replicates cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 M: 5f45ddefab50f1d57f54ef53d736f1096256449f 192.168.18.177:7003 slots:[10923-16383] (5461 slots) master 1 additional replica(s) M: 5515163a16503a5892e0d0fc14a5b292d76216c0 192.168.18.177:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 57ef0adbb38bb8caf9616873834dc60d8b2a1d74 192.168.18.177:7004 slots: (0 slots) slave replicates 5f45ddefab50f1d57f54ef53d736f1096256449f
-
Can I set the above configuration? (type ‘yes’ to accept): yes
-
连接验证
-
redis-cli -c -p 7001
-
查看集群信息: cluster nodes
57ef0adbb38bb8caf9616873834dc60d8b2a1d74 192.168.18.177:7004@17004 slave 5f45ddefab50f1d57f54ef53d736f1096256449f 0 1558167694000 4 connected 3e88c6431b67db01a3f37cb73668edd36003b4cf 192.168.18.177:7006@17006 slave 5515163a16503a5892e0d0fc14a5b292d76216c0 0 1558167695000 6 connected 4603f8973e3f641ae839872a5b3e963e19a7de07 192.168.18.177:7005@17005 slave cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 0 1558167695963 5 connected cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 192.168.18.177:7001@17001 master - 0 1558167694000 1 connected 0-5460 5f45ddefab50f1d57f54ef53d736f1096256449f 192.168.18.177:7003@17003 master - 0 1558167693000 3 connected 10923-16383 5515163a16503a5892e0d0fc14a5b292d76216c0 192.168.18.177:7002@17002 myself,master - 0 1558167692000 2 connected 5461-10922
-
-
SpringBoot连接redis集群
spring: redis: cluster: nodes: - 192.168.18.177:7001 - 192.168.18.177:7002 - 192.168.18.177:7003 - 192.168.18.177:7004 - 192.168.18.177:7005 - 192.168.18.177:7006 jedis: pool: max-idle: 100 min-idle: 1 max-active: 1000 max-wait: -1
-
分布式锁的实现方式
- 数据库的乐观锁
- 基于Redis的分布式锁
- 基于zookeeper的分布式锁
-
为了确保分布式锁的可用,至少要确保锁的实现同时满足以下4个条件
- 互斥性:在任意时刻,只有一个客户端能持有锁
- 不会发生死锁: 即使有一个客户端在持有锁期间发生崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
- 具有容错性: 只要大部分节点的Redis正常运行,客户端就可以加锁和解锁。
- 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给结了。
-
分布式锁的简单实现
package com.swkang.springboot.springbootredissentinel.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.util.UUID; import java.util.concurrent.TimeUnit; @Service public class RedisUtil { @Autowired private StringRedisTemplate redisTemplate; private String key = "lock_key"; /** * 基于Redis实现分布式加锁 * @param waitTime 加锁等待时间 * @param timeOut 锁的保存时间 * @return 返回非空字符串,加锁成功 */ public String lock(int waitTime, int timeOut){ try { String uuid = UUID.randomUUID().toString(); Long endTime = System.currentTimeMillis() + waitTime; while(System.currentTimeMillis() < endTime){ if(redisTemplate.opsForValue().setIfAbsent(key, uuid, timeOut, TimeUnit.SECONDS)){ return uuid; } } }catch (Exception e){ e.printStackTrace();; } return null; } /** * 释放锁 * @param uuid */ public void unlock(String uuid){ try { if(redisTemplate.opsForValue().get(key).equals(uuid)){ redisTemplate.delete(key); } } catch (Exception e){ e.printStackTrace(); } } }
Redis5.0从入门到精通
最新推荐文章于 2024-09-29 12:55:09 发布