首页 > 数据库 >Redis

Redis

时间:2024-02-21 13:45:07浏览次数:31  
标签:AOF Redis redis 获取 key 集合

Redis

Redis 是基于 Open Source BSD 协议,使用 C 语言编写的一种Key-Value(键值对)内存数据库

image-20231103092238991

安装image-20231103090917790

工具

image-20231103092059805

启动服务端

redis-server /root/myredisconf/redis.conf -使用指定配置文件启动

启动客户端连接

redis-cli -a root -p 6379 用密码和端口登录授权

10大数据类型

image-20231103212750929

1.String

set key value 设置指定 key 的值

  • EX seconds – 设置键key的过期时间,单位时秒
  • PX milliseconds – 设置键key的过期时间,单位时毫秒
  • NX – 只有键key不存在的时候才会设置key的值
  • XX – 只有键key存在的时候才会设置key的值
  • KEEPTTL -- 获取 key 的过期时间
  • GET -- 返回 key 存储的值,如果 key 不存在返回空

get key 获取指定 key 的值

MGET 获取所有(一个或多个)给定 key 的值
MSET 同时设置一个或多个 key-value 对
MSETNX 同时设置一个或多个 key-value 对,得都不存在才插入

GETRANGE 返回 key 中字符串值的子字符
SETRANGE 从偏移量 offset 开始用 value 覆写给定 key 所储存的字符串值

INCR 将 key 中储存的数字值增一
INCRBY 将 key 所储存的值加上给定的增量值 ( increment )
DECR 将 key 中储存的数字值减一
DECRBY 将 key 所储存的值减去给定的减量值 ( decrement )

STRLEN 返回 key 所储存的字符串值的长度
APPEND 将 value 追加到 key 原来的值的末尾

GETSET 将给定 key 的值设为 value ,并返回 key 的旧值 ( old value )

image-20231104104758545

2.List

List 是 Redis 中最常用数据类型。值value 中存储的是列表。

LPUSH 将一个或多个值插入到列表头部
RPUSH 在列表中添加一个或多个值
LRANGE 获取列表指定范围内的元素

LPOP 移出并获取列表的第一个元素
RPOP 移除并获取列表最后一个元素

LINDEX 通过索引获取列表中的元素

LLEN 获取列表长度

LREM 移除指定个数的列表元素

LTRIM 对一个列表进行修剪(trim),保留指定开始到结束

RPOPLPUSH 移除列表的最后一个元素,并将该元素添加到另一个列表并返回

LSET 通过索引设置列表元素的值

LINSERT before/after在列表的元素前或者后插入元素

BLPOP 移出并获取列表的第一个元素
BRPOP 移出并获取列表的最后一个元素
BRPOPLPUSH 从列表中弹出一个值,并将该值插入到另外一个列表中并返回它
LPUSHX 将一个值插入到已存在的列表头部
RPUSHX 为已存在的列表添加值

image-20231104131435681

3.Hash

Hash(哈希散列)是 Redis 基本数据类型,值value 中存储的是 hash 表。Hash 特别适合用于存储对象。常用的命令:

HSET 用于设置存储在 key 中的哈希表字段的值也可以多次
HGET 获取存储在哈希表中指定字段的值
HMGET 获取存储在哈希表中指定字段的值
HGETALL 获取在哈希表中指定 key 的所有字段和值
HDEL 用于删除哈希表中一个或多个字段

HKEYS 获取存储在 key 中的哈希表的所有字段
HVALS 用于获取哈希表中的所有值

HEXISTS 用于判断哈希表中字段是否存在
HINCRBY 为存储在 key 中的哈希表指定字段做整数增量运算
HLEN 获取存储在 key 中的哈希表的字段数量

hsetnx 没有就加入

image-20231104132628847

4.set

SADD key member1 [member2] 向集合添加一个或多个成员
SMEMBERS 返回集合中的所有成员
SISMEMBER 判断 member 元素是否是集合 key 的成员
SREM 移除集合中一个或多个成员
SCARD 获取集合的成员数

SRANDMEMBER 返回集合中一个或多个随机数
SPOP 移除并返回集合中的一个随机元素
SMOVE 将 member 元素从 source 集合移动到 destination 集合

集合运算
SDIFF 返回给定所有集合的差集
SDIFFSTORE 返回给定所有集合的差集并存储在 destination 中
SINTER 返回给定所有集合的交集
SINTERCARD numkeys key [key ...] [LIMIT limit] 返回给定所有集合的交集个数
SINTERSTORE 返回给定所有集合的交集并存储在 destination 中

SUNION 返回所有给定集合的并集
SUNIONSTORE 所有给定集合的并集存储在 destination 集合中
SSCAN 迭代集合中的元素

应用

image-20231104175350009

image-20231104175329311

5.有序集合zset(sorted set)

ZADD key score member [score member ...] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZRANGE key end [withscores] 通过索引区间返回有序集合成指定区间内的成员
ZREVRANGE 返回有序集中指定区间内的成员,通过索引,分数从高到底
ZRANGEBYSCORE 通过分数返回有序集合指定区间内的成员 加一个括号变成不包括边界

ZSCORE 返回有序集中,某个成员的分数值
ZCARD 获取有序集合的成员数
ZREM 移除有序集合中的一个或多个成员
ZINCRBY 有序集合中对指定成员的分数加上增量 increment
ZCOUNT 计算在有序集合中指定区间分数的成员数
zmpop 从键名列表中的第一个非空排序集中弹出一个或多个元素,它们是成员分数对

ZRANK 返回有序集合中指定成员的索引
ZREVRANK 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

ZINTERSTORE 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
ZLEXCOUNT 在有序集合中计算指定字典区间内成员数量
ZRANGEBYLEX 通过字典区间返回有序集合的成员
ZREMRANGEBYLEX 移除有序集合中给定的字典区间的所有成员
ZREMRANGEBYRANK 移除有序集合中给定的排名区间的所有成员
ZREMRANGEBYSCORE 移除有序集合中给定的分数区间的所有成员
ZREVRANGEBYSCORE 返回有序集中指定分数区间内的成员,分数从高到低排序
ZUNIONSTORE 计算一个或多个有序集的并集,并存储在新的 key 中
ZSCAN 迭代有序集合中的元素(包括元素成员和元素分值)

应用

image-20231105092241210

6.位图bitmap

setbit key offset value 键 偏移位 只能零或者1

getbit key offset

strlen 统计字节数占用多少 每8位算一个字节(扩容)

bitcount key [start end] 是用来统计某一个二进制串里面1的个数

bitop operation destkey key [key] 主要对于多个对应key的二进制串,做and,or,xor, not操作。结果存入destkey 。

应用

image-20231105095457968

7.HyperLogLog

去重复统计功能的基数估计算法-就是HyperLogLog

PFADD key element [element ...] 将指定元素加入到给定的HyperLogLog中。

PFCOUNT key [key ...] 返回给定HyperLogLog的基数估算值。

PFMERGE destkey sourcekey [sourcekey ...] 将多个HyperLogLog合并为一个HyperLogLog。

应用

image-20231105100820794

8.Redis GEO地理空间

Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。

底层是zset ,所以用zrange也可以

如果有乱码问题加参数 redis- cli-a111111 --raw

GEOADD key longitude latitude member [longitude latitude member ...] 用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

GEOPOS key member [member ...] 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。

GEOHASH key member [member ...] 用于获取一个或多个位置元素的 geohash 值。

GEODIST key member1 member2 [m|km|ft|mi] 用于返回两个给定位置之间的距离。

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] georadiusbymember 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。

应用

image-20231105102624915

9.流Stream

Redis Stream 是Redis5.0推出的一种专门用来处理消息队列场景的高级数据结构,是Redis下消息队列的最佳实现。

实现消息队列,它支持消息的持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,让消息队列更加的稳定和可靠

image-20231105133517858

消息队列的相关命令:
XADD:添加消息到末尾(生产消息)XADD key ID field value [field value ...]
XTRIM:对流进行修剪,限制长度 XTRIM key MAXLEN [~] count
XDEL:删除消息 XDEL key ID [ID ...]
XLEN:获取流包含的元素数量,及消息长度 XLEN key
XRANGE:获取消息列表,会自动过滤已经删除的消息 XRANGE key start end [COUNT count]
XREVERANGE:反向获取消息列表,ID从大到小 XREVRANGE key end start [COUNT count]
XREAD:以阻塞或非阻塞方式获取消息列表(消费消息) XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
消费者组相关命令:
XGROUP CREATE:创建消费者组 XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
XREADGROUP GROUP:读取消费者组中的消息 XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
XACK:将消息标记为“已处理”
XGROUP SETID:为消费者组设置新的最后递送消息ID
XGROUP DELCONSUMER:删除消费者
XGROUP DESTROY:删除消费者组
XPENDING:显示待处理消息的相关信息
XCLAIM:转移消费者组的相关信息
XINFO GROUPS:打印消费者组的信息
XINFO STREAM:打印流信息

10.位域(bitfield)

位域修改 溢出控制

将一个Redis字符串看作是一个由二进制位组成的数组并能对变长位宽和任意没有字节对产的指定整型位域进行寻址和修改

Redis持久化

RDB(Redis 数据库): RDB 持久性以指定的时间间隔执行数据集的时间点快照。

image-20231105145315212

RDF

image-20231106101911843

后续集群时要修改dump文件名称

image-20231106102901579

备注:不可以把备份文件dump.rdb和生产redis服务器放在同一台机器,必须分开各自存储,以防生产机物理损坏后备份文件也挂了。

image-20231106104407375

优势

适合大规模的数据恢复、按照业务定时备份、对数据完整性和一致性要求不高、RDB 文件在内存中的加载速度要比 AOF 快得多

image-20231106105012004

使用redis-check-rdb工具修复rdb文件

哪些情况会触发RDB快照

image-20231106114623374

禁用快照

1.动态所有停止RDB保存规则的方法: redis-cli config set save

2.修改配置文件 set “”(推荐

其他配置

image-20231106115129540

stop-writes-on-bgsave-error:如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求 --默认yes

rdbcompression:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能 --默认yes

rdbchecksum:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能 --默认yes

rdb-del-sync-files:在没有持久性的情况下删除复制中使用的RDB文件启用。 默认情况下no,此选项是禁用的。

AOF

AOF 则是通过保存Redis服务器所执行的写命令来记录数据库状态。

工作流程

序号 过程
1 Client作为命令的来源,会有多个源头以及源源不断的请求命令。
2 在这些命令到达Redis Server 以后并不是直接写入AOF文件,会将其这些命令先放入AOF缓存中进行保存。这里的AOF缓冲区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作。
3 AOF缓冲会根据AOF缓冲区同步文件的三种写回策略将命令写入磁盘上的AOF文件。
4 随着写入AOF内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而起到AOF文件压缩的目的。
5 当Redis Server 服务器重启的时候会从AOF文件载入数据。

写会策略

image-20231106194449755

image-20231106195422575

修复

image-20231106201628853

优点:更好的保护数据不丢失 、性能高、可做紧急恢复

缺点:相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb,aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

image-20231106203544257

重写原理:

1:在重写开始前,redis会创建一个“重写子进程”,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
2:与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
3:当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中
4:当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中
5:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似

image-20231110101750064

RDB-AOF混合持久化

在同时开启rdb 和aof 持久化时,重启时只会加载 aof 文件,不会加载 rdb 文件

推荐方式:

1 开启混合方式设置

​ 设置aof-use-rdb-preamble的值为 yes yes表示开启,设置为no表示禁用

2 RDB+AOF的混合方式---------> 结论:RDB镜像做全量持久化,AOF做增量持久化

​ 先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,既保证了数据完整性,又提高了恢复数据的性能。简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。----》AOF包括了RDB头部+AOF混写

纯缓存模式:

image-20231110102549943

Redis事务

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞

redis事务命令

命令 描述
DISCARD 取消事务,放弃执行事务块内的所有命令
EXEC 执行所有事务块内的命令
MULTI 标记一个事务块的开始
UNWATCH 取消 WATCH 命令对所有 key 的监视
WATCH 监视一个(或多个) key

1.正常执行

//开启事务
multi
    
//执行事务    
exec    

2.放弃事务

//开启事务
multi
    
//放弃事务  
discard 

3.全体连坐

指检查出语法错误全体加入队列失败

4.冤头债主

指通过语法检查,但比如对string类型执行自增操作,程序报错,但其他操作会正常执行

5.watch

  悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
  乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁策略:提交版本必须 大于 记录当前版本才能执行更新
      
Redis使用Watch来提供乐观锁定,类似于CAS(Check-and-Set)     

image-20231110105451433

6.unwatch

image-20231110105543117

小结

1.一旦执行了exec之前加的监控锁都会被取消掉了
2.当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视

Redis管道pipeLine

管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完完毕后,通过一条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。

image-20231110110524229

Redis复制(replica)

就是主从复制,master以写为主,Slave以读为主
当master数据变化的时候,自动将新的数据异步同步到其它slave数据库

读写分离、容灾恢复、数据备份、水平扩容支撑高并发

基本操作命令

image-20231111141742296

修改配置文件细节操作

image-20231111144110261

常见问题:
​ 1.从机可以执行写命令吗? 从机不能写,做到主从读写分离
​ 2.主机shutdown后,从机会上位吗? 从机不动,原地待命,从机数据可以正常使用;等待主机重启动归来
​ 3.主机shutdown后,重启后主从关系还在吗? 从机还能否顺利复制? 还在,能顺利复制
​ 4.某台从机down后,master继续,从机重启后它能跟上大部队吗? 可以继续跟上,首次一锅端,后续跟随,master写,slave跟

image-20231111155210770

但是重启后关系不见了

上一个slave可以是下一个slave的master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻主master的写压力

image-20231112092838055

Redis哨兵(sentinel)

​ 吹哨人巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务

作用

主从监控 监控主从redis库运行是否正常
消息通知 哨兵可以将故障转移的结果发送给客户端
故障转移 如果Master异常,则会进行主从切换将其中一个Slave作为新Master
配置中心 客户端通过连接哨兵来获得当前Redis服务的主节点地址

配置

image-20231112094615054

在master断开连接后,数据依然在,会从剩下的slave选出一个master,当原来的master连回来时,原来的master会转换身份,变为slave

image-20231112102036396

哨兵的运行流程和原理

image-20231112102736128

Raft算法

image-20231112103145435

master上位流程

image-20231112103740304

Redis集群(cluster)

image-20231112105059955 image-20231113102313914

slot槽位映射,一般业界有3种解决方案:哈希取余分区、一致性哈希算法分区(数据倾斜问题)、哈希槽分区

哈希槽经典面试题:为什么redis集群的最大槽数是16384个?

(1)如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。

在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是: 65536÷8÷1024=8kb

在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为16384时,这块的大小是: 16384÷8÷1024=2kb

因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。

(2)redis的集群主节点数量基本不可能超过1000个。

集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者不建议redis cluster节点数量超过1000个。 那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

(3)槽位越小,节点少的情况下,压缩比高,容易传输

Redis主节点的配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。 如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

cluster nodes查看并检验集群状态

cluster info 集群信息

使用集群后要以集群方式读写 登录要加-c

redis-cli -a 111111-p 6381-c

查看某个key该属于对应的槽位值

CLUSTER KEYSLOT 键名称

主从切换、对调

CLUSTER FAILOVER

重新分派槽号

reshard

分配从节点

redis-cli -a 密码 --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID

删除从节点

命令:redis-cli -a 密码 --cluster del-node ip:从机端口 从机节点ID

主从扩容和主从缩容

image-20231114102716635

cluster-require-full-coverage: 默认值 yes , 即需要集群完整性,方可对外提供服务 通常情况,如果这3个小集群中,任何一个(1主1从)挂了,你这个集群对外可提供的数据只有2/3了, 整个集群是不完整的, redis 默认在这种情况下,是不会对外提供服务的。

CLUSTER COUNTKEYSINSLOT 槽位数字编号

CLUSTER KEYSLOT 键名称

Spring Boot集成Redis

jedis - lettuce - RedisTemplate(推荐)三者的联系

jedis

image-20231115094302868

@Component
public class JedisDemo {
    public static void main(String[] args) throws InterruptedException {
        //1. connection获得,通过指定ip和端口号
        Jedis jedis = new Jedis("192.168.169.129", 6380);

        //2. 指定访问服务器的密码
        jedis.auth("root");
        System.out.println(jedis.ping());

        Set<String> keys = jedis.keys("*");
        System.out.println(keys);

        jedis.set("kv","hello springboot");
        System.out.println(jedis.get("kv"));
        System.out.println(jedis.ttl("kv"));
        jedis.expire("kv",20);
        Thread.sleep(1000*3);
        System.out.println(jedis.ttl("kv"));

        jedis.lpush("list","11","12","13","123");
        System.out.println(jedis.lrange("list",0,-1));
        
    }
}

image-20231115100751473

Lettuce

加入依赖

<dependency>
  <groupId>io.lettuce</groupId>
  <artifactId>lettuce-core</artifactId>
  <version>6.2.1.RELEASE</version>
</dependency>

业务

@Component
public class LettuceDemo {
    public static void main(String[] args) {
        //1.使用构建器 RedisURI.builder
        RedisURI uri = RedisURI.builder()
                .redis("192.168.169.129")
                .withPort(6380)
                .withAuthentication("default","root")
                .build();

        //2.创建连接客户端
        RedisClient redisClient = RedisClient.create(uri);
        StatefulRedisConnection connect = redisClient.connect();

        //3.通过conn创建换作的command
        RedisAsyncCommands commands = connect.async();

        //业务
        commands.set("kv2","hello springboot2");
        System.out.println(commands.get("kv2"));
        
        //4.各种关闭资源
        connect.close();
        redisClient.shutdown();

    }
}

RedisTemplate

导入依赖

        <!--SpringBoot与Redis整合依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

service层

@Slf4j
@Service
public class OrderService {
    public static final String ORDER_KEY = "order:";

//    @Autowired
//    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate; //改用StringRedisTemplate解决序列化问题

    public void addOrder()
    {
        int keyId = ThreadLocalRandom.current().nextInt(1000)+1;
        String orderNo = UUID.randomUUID().toString();
//        redisTemplate.opsForValue().set(ORDER_KEY+keyId,"京东订单"+ orderNo);
        stringRedisTemplate.opsForValue().set(ORDER_KEY+keyId,"京东订单"+ orderNo);
        log.info("=====>编号"+ORDER_KEY+keyId+"的订单流水生成:{}",orderNo);
    }

    public String getOrderById(Integer id)
    {
//        return (String)redisTemplate.opsForValue().get(ORDER_KEY + id);
        return stringRedisTemplate.opsForValue().get(ORDER_KEY + id);
    }

序列化问题

键(key)和值 (value)都是通过Spring提供的Serializer序列化到数据库的。
RedisTemplate默认使用的是JdkSerializationRedisSerializer.StringRedisTemplate默认使用的是StringRedisSerializer。KEY被序列化成这样,线上通过KEY去查询对应的VALUE常不方

方案一

使用StringRedisTemplate,但是在get key的时候也会有乱码,这时需要在登录时使用redis-cli -a root -p 6380 --raw

方案二

使用StringRedisSerializer()序列化方式

@Configuration
public class RedisConfig
{
    /**
     * redis序列化的工具配置类,下面这个请一定开启配置
     * 127.0.0.1:6379> keys *
     * 1) "ord:102"  序列化过
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,没有序列化过
     * this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法
     * this.redisTemplate.opsForList(); // 提供了操作list类型的所有方法
     * this.redisTemplate.opsForSet(); //提供了操作set的所有方法
     * this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法
     * this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory)
    {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

集群环境问题

故障描述:SpringBoot客户端没有动态感知到RedisCluster的最新集群信息

导致原因:SpringBoot 2.X 版本,Redis默认的连接池采用 Lettuce当Redis 集群节点发生变化后,Letture默认是不会刷新节点拓扑

解决方案:1. 排除lettuce采用jedis (不推荐)2 .重写连接工厂实例 (极度不推荐) 3 .刷新节点集群拓扑动态感应官网

 server.port=7777

spring.application.name=redis7_study

# ========================logging=====================
logging.level.root=info
logging.level.com.atguigu.redis7=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n 

logging.file.name=D:/mylogs2023/redis7_study.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

# ========================swagger=====================
spring.swagger2.enabled=true
#在springboot2.6.X结合swagger2.9.X会提示documentationPluginsBootstrapper空指针异常,
#原因是在springboot2.6.X中将SpringMVC默认路径匹配策略从AntPathMatcher更改为PathPatternParser,
# 导致出错,解决办法是matching-strategy切换回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher


# ========================redis集群=====================
spring.redis.password=111111
# 获取失败 最大重定向次数
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.174:6385,192.168.111.174:6386

Redis管理 redis 服务相关命令

命令 描述
BGREWRITEAOF 异步执行一个 AOF(AppendOnly File) 文件重写操作
BGSAVE 在后台异步保存当前数据库的数据到磁盘
CLIENT 关闭客户端连接
CLIENT LIST 获取连接到服务器的客户端连接列表
CLIENT GETNAME 获取连接的名称
CLIENT PAUSE 在指定时间内终止运行来自客户端的命令
CLIENT SETNAME 设置当前连接的名称
CLUSTER SLOTS 获取集群节点的映射数组
COMMAND 获取 Redis 命令详情数组
COMMAND COUNT 获取 Redis 命令总数
COMMAND GETKEYS 获取给定命令的所有键
TIME 返回当前服务器时间
COMMAND INFO 获取指定 Redis 命令描述的数组
CONFIG GET 获取指定配置参数的值
CONFIG REWRITE 修改 redis.conf 配置文件
CONFIG SET 修改 redis 配置参数,无需重启
CONFIG RESETSTAT 重置 INFO 命令中的某些统计数据
DBSIZE 返回当前数据库的 key 的数量
DEBUG OBJECT 获取 key 的调试信息
DEBUG SEGFAULT 让 Redis 服务崩溃
FLUSHALL 删除所有数据库的所有 key
FLUSHDB 删除当前数据库的所有 key
INFO 获取 Redis 服务器的各种信息和统计数值
LASTSAVE 返回最近一次 Redis 成功将数据保存到磁盘上的时间
MONITOR 实时打印出 Redis 服务器接收到的命令,调试用
ROLE 返回主从实例所属的角色
SAVE 异步保存数据到硬盘
SHUTDOWN 异步保存数据到硬盘,并关闭服务器
SLAVEOF 将当前服务器转变从属服务器(slave server)
SLOWLOG 管理 redis 的慢日志
SYNC 用于复制功能 ( replication ) 的内部命令

面试题

redis到底是单线程还是多线程?

redis4之后才慢慢支持多线程,直到redis6/7后才稳定。

lO多路复用听说过吗?

redis为什么快?

基于内存操作: Redis 的所有数据都存在内存中,因此所有的运算都是内存级别的,所以他的性能比较高;

数据结构简单:Redis 的数据结构是专门设计的,而这些简单的数据结构的查找和操作的时间大部分复杂度都是O(1),因此性能比较高:

多路复用和非阻塞I/O:Redis使用I/O多路复用来监听多个 socket连客端,这样就可以使用一个线程连接来处理多人请求,减少线程切换带来的开销,同时也避免了I/O 阻塞

避免上下文切换:因为是单线程模型,因此就避免了不必要的上下文切换和多线程竞争,这就省去了多线程切换带来的时间和性能上的消耗,而且单线程不会导致死锁问题的发生

标签:AOF,Redis,redis,获取,key,集合
From: https://www.cnblogs.com/sukidakaraDCL/p/18025017

相关文章

  • redis
    RedisRedis是基于OpenSourceBSD协议,使用C语言编写的一种Key-Value(键值对)内存数据库安装工具启动服务端redis-server/root/myredisconf/redis.conf-使用指定配置文件启动启动客户端连接redis-cli-aroot-p6379用密码和端口登录授权10大数据类型1.String......
  • 05 内存快照:宕机,Redis如何快速恢复?
    内存快照:指内存中的数据在某一个时刻的状态以文件的形式写到磁盘上,类似于照片。快照文件就称为RDB文件,其中,RDB就是RedisDataBase的缩写。两个关键问题:对哪些数据做快照?关系到快照的执行效率问题;做快照时,数据还能被增删改吗?关系到Redis是否被阻塞,能否同时正常处理请求......
  • 04 AOF日志:宕机,Redis如何避免数据丢失
    Redis的持久化主要有两大机制,即AOF(AppendOnlyFile)日志和RDB快照。Redis用于避免数据丢失的AOF方法数据库的写前日志(WriteAheadLog,WAL),在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。AOF日志正好相反,是写后日志,Redis是先执行命令,把数据写入内......
  • redis自学(1) 动态字符串SDS
      字符串是redis最常见的数据结构,但redis并没有直接使用C语言的字符串,是因为C语言本身其实是没有字符串的,所谓的字符串其实是字符数组(Java语言中的字符串是一个对象),所以C语言的字符串有很多问题:①获取字符串长度需要通过运算C语言的字符串数组都是以’\0’结尾,这是一个字符......
  • 认识Redis:不只是缓存,还有这些厉害的功能!
    在当今数据驱动的世界中,快速存取信息成为了技术发展的关键。而在众多存储解决方案中,Redis以其独特的魅力和强大的功能,成为了开发者们的宠儿。今天,就让我们一起来认识一下Redis。一、Redis是什么,可以用来干什么?Redis,英文全称是RemoteDictionaryServer(远程字典服务),是一个开源......
  • 4-Redis十大关系之哈希Hash
    Redis十大关系之哈希Hash:Map<String,Map<Object,Object>>HSETkeyfieldvaluefieldvalue...:设置属性值HGETkeyfield:获取对应属性值HGETALLkey:遍历哈希HDELkeyfield:删除field对应的属性HLENkey:获取某个key内的全部数量HEXISTSkeyfield:判断key中有没有fie......
  • NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数
    NoSQL数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能!【官网地址】:http://www.redisant.cn/nosql介绍直观的用户界面从单一应用程序中同时连接Redis、Memcached、SSDB、LevelDB、RocksDB,你可以快速轻松地创建......
  • Redis3主3从+pg1主2从
    目录一、环境准备二、安装服务器部署redis集群1.安装需求2.创建redis3.上传软件4.编译安装4.1编译安装root用户编译否则问题一4.2验证安装是否成功4.3操作过程5.新建redis集群配置文件5.1新建配置文件目录,复制模板配置文件5.2修改默认配置文件6.部署步骤6.1启动redi......
  • 3-Redis十大关系之列表List
    Redis十大类型之ListList适用于单key多value的情况。底层是由双端链表组成。LPUSH:LPUSHkeyv1v2v3...从左边插入RPUSH:RPUSHkeyV1V2V3V4V5...从右边插入LRANGEkeystartend:进行遍历,注意不存在RRANGE!LPOP和RPOP:分别是从左边移除一个元素和右边移除一个元素......
  • redis高频问题--redis单线程
    redis单线程问题引入●Redis是纯内存操作,执行速度非常快●采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题●使用I/O多路复用模型,非阻塞IORedis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,I/O多路复用模型主要就是实现......