为了高性能与高并发
redis基础
常用数据结构
- String 常用于需要计数的场景
- list 发布与订阅或者说消息队列、慢查询
- hash 系统中对象数据的存储。
- set 不能重复的数据
- sorted set 需要对数据根据某个权重进⾏排序
redisTemplate 常用操作: https://blog.csdn.net/lydms/article/details/105224210
设置过期时间
内存是有限的,如果一直保存,会存在空间存储溢出
127.0.0.1:6379> exp key 60 # 数据在 60s 后过期
(integer) 1
127.0.0.1:6379> setex key 60 value # 数据在 60s 后过期 (setex:[set] + [ex]pire)
OK
127.0.0.1:6379> ttl key # 查看数据还有多久过期
(integer) 5
Redis中除了字符串类型有⾃⼰独有设置过期时间的命令 setex 外,其他⽅法都需要依靠 expire 命令来设置过期时间 。另外, persist 命令可以移除⼀个键的过期时间
过期数据的删除策略
如果没有设置过期时间,默认是永久保存的
- 惰性删除, 在取出时进行过期检查
- 定期删除: 每隔一段时间就抽取一批进行删除检查
redis 中采用的是定期加惰性删除的策略
定期与惰性删除会漏掉很多过期key,解决措施就是内存淘汰机制
内存淘汰机制
如果存储数据超出redis 设置的内存大小,就会触发内存淘汰机制
默认触发的是noeviction ,写入失败
//在redis.conf中
maxmemory
// 命令行方式操作
//获取maxmemory配置参数的大小
127.0.0.1:6379> config get maxmemory
//设置maxmemory参数为100mb
127.0.0.1:6379> config set maxmemory 100mb
内存淘汰策略公有八种Redis4.0实现了6种淘汰策略,4.0之后又增加了2种策略
LRU 表示最近最少使用,LFU 表示最不常用
淘汰策略可以分为:
- 会在所有数据中淘汰的: allkeys-lru、allkeys-random、allkeys-lfu
- volatile-ttl:根据键的ttl(生存时间值),删除设置过期时间最近的键,先过期的被先删除。
- volatile-random:random也就是随机,设置了过期的 key 会随机的删除。
- volatile-lru:在设置过期时间的 key,使用LRU算法筛选淘汰键。
- volatile-lfu:在设置过期时间的 key,使用LFU算法筛选淘汰键。
- 会在设置过期时间数据中淘汰的:volatile-lru、volatile-random、volatile-ttl、volatile-lfu
- allkeys-random:在所有键中随机淘汰数据。
- allkeys-lru:在所有键中使用LRU算法筛选数据。
- allkeys-lfu:在所有键中使用lfu算法筛选数据。
使用建议:
- 优先使用 allkeys-lru 策略。这样,可以充分利用 LRU 这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果你的业务数据中有明显的冷热数据区分,我建议你使用 allkeys-lru 策略。
- 如果业务应用中的数据访问频率相差不大,没有明显的冷热数据区分,建议使用allkeys-random 策略,随机选择淘汰的数据就行。
- 如果你的业务中有置顶的需求,比如置顶新闻、置顶视频,那么,可以使用 volatile-lru策略,同时不给这些置顶数据设置过期时间。这样一来,这些需要置顶的数据一直不会被删除,而其他数据会在过期时根据 LRU 规则进行筛选。
淘汰数据注意:
如果数据中存在脏数据(与mysql查询相比被修改过的数据),请及时修改同步到数据库.因为redis淘汰数据不会在意数据是干净还是脏数据.
// redis.conf设置淘汰机制
maxmemory-policy
//命令行设置内存淘汰机制
//获取maxmemory-policy配置
127.0.0.1:6379> config get maxmemory-policy
// 设置maxmemory-policy配置为allkeys-lru
127.0.0.1:6379> config set maxmemory-policy allkeys-lru
flushall 清空所有数据—命令行内
监控 redis 内存数据
使用redis-cli -a xxx info memory > memory.txt将内存信息保存到文件(xxx是密码)
或 info memory 获取内存数据
info 重要参数
属性名 | 属性说明 |
---|---|
used_memory | Redis 分配器分配的内存总量,也就是内部存储的所有数据内存占用量 |
used_memory_human | 以可读的格式返回 used_memory |
used_memory_rss | 从操作系统的角度显示 Redis 进程占用的物理内存总量 |
used_memory_rss_human | used_memory_rss 的用户宜读格式的显示 |
used_memory_peak | 内存使用的最大值,表示 used_memory 的峰值 |
used_memory_peak_human | 以可读的格式返回 used_memory_peak的值 |
used_memory_lua | Lua 引擎所消耗的内存大小。 |
mem_fragmentation_ratio | used_memory_rss / used_memory 的比值,可以代表内存碎片率 |
maxmemory | Redis 能够使用的最大内存上限,0表示没有限制,以字节为单位。 |
maxmemory_policy | Redis 使用的内存回收策略,可以是 noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random 或者 volatile-ttl。默认是noeviction,也就是不会回收。 |
重启恢复
AOF 顺序写记录命令 与 RDB 做快照文件
redis新版允许兼容使用
redis 架构
主从架构 与 分片集群
主从架构,是多台服务器复制主服务器数据,
分片集群是 数据分片存储到不同节点上
事务
redis 可以通过MULTI ,EXEC,DISCARD 和 watch
> MULTI // 开启后可以输入多个命令
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC /// 执行
1) (integer) 1
2) (integer)
消息队列
redis 5.0新增了一个数据结构 Stram 可以做数据结构
- 发布 / 订阅模式
- 按照消费者组进行消费
- 消息持久化( RDB 和 AOF)
redis和mysql数据库同步
利用数据库本身进行手动同步
- 在mysql 中对要操作 的数据设置触发器Triggr,监听操作
- 客户端(NodeServer)向MySQL中写入数据时,触发器会被触发,触发之后调用MySQL的UDF函数
- udf函数 可以把数据库写入到Redis中,从而达到同步的效果
好处
同步效率比较高,一般结合延迟双删和缓存超时策略进行手动同步
延迟双删和缓存超时简介
首先删除redis中的数据,然后更新数据库中的数据,最后过一段时间(大概一分钟)再对redis中数据做一次删除.这样就可能尽量保证我们的redis数据被删掉,但极端情况下,旧数据还是没有删掉,所以我们设计让它的过期时间短一点,这样就算没删掉也可以很快过期.
利用Canal进行数据同步
Canal简介
阿里旗下,用来监控数据库内部数据变化的软件.
Canal会伪装成mysql的备份机.当mysql进行数据操作以后,会将记录记载到日志中,同时发送给备份机,当canal接收到日志数据后,就会进行后续数据同步工作.
数据更新(以首页广告更新为例)
当mysql内部的数据发生改变之后.我们的数据监控微服务,就可以根据canal获取到最新更新的数据.,将我们的position字段的值提取出来(代表当前广告的位置),之后数据监控的微服务就会把这个值发送到rabbitmq上,rabbitmq收到这个消息后,就会把这个消息保存到自己的内存中.这时运营的微服务就会从rabbitmq中把值拿出来,调用nginx中的更新数据的lua脚本进行数据更新.
- 解析MySQL的binlog实现,将数据库中的数据同步到Redis