redis丨青训营笔记

67 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第17天

什么是redis

Redis基本工作原理Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用。同时支持strings,lists,hashes,sets,sorted sets,bitmaps,hyperloglogs和geospatial indexes等数据类型。它还内建了复制,lua脚本,LRU,事务等功能,通过redis sentinel实现高可用,通过redis cluster实现了自动分片。以及事务,发布/订阅,自动故障转移等等。

  • 数据从内存中读写

  • 数据保存到硬盘上防止重启数据丢失

    • 增量数据保存到AOF文件
    • 全量数据RDB文件
  • 单线程处理所有操作命令

Redis那么快,除了单线程、基于内存等,还有它特殊的数据结构。

Redis应用实例

连续签到

  • 在Redis中设置一个值,后天的0点过期
  • String数据结构,sds,使用在存储计数、Session

消息通知

用list作为消息队列

  • 使用场景:消息通知

  • List数据结构:Quicklist

    • 由一个双向链表和listpack实现

计数

一个用户有多项计数需求,可通过hash结构存储

  • Hash数据结构dict
  • rehash:迁移某一个哈希节点下的值到另一个节点,数据量大时会阻塞用户请求
  • 渐进式rehash:每次用户访问都迁移少量数据,平摊所有的迁移开销

排行榜

积分变化时,排名要实时变更

  • zset数据结构,zskiplist跳表
  • 结合dict后,可实现通过key操作跳表

限流

要求1秒内放行的请求为N,超过N禁止访问

利用当前时间戳构造一个key,对这个key调用incr,实现访问计数。

分布式锁

并发场景,要求一次只能有一个协程执行。执行完成后,其它等待中的协程才能执行。

可以使用redis的setnx实现,利用了两个特性

  • Redis单线程执行命令
  • setnx只有未设置过才能执行成功

但这并不是高可用的实现,因为可能会被超时的任务阻塞。

Redis使用注意事项

大Key,热Key

数据类型大key标准
String类型value的字节数大于10KB
Hash/Set/Zset/list等复杂数据结构类型元素个数大于5000个或总value字节数大于10MB
  • 读取成本高
  • 容易导致慢查询
  • 主从复制异常,服务阻塞无法正常响应请求

消除大Key的方法:

集合类结构hash、list、set、set

(1)拆分:可以用hash取余、位掩码的方式决定放在哪个key中

(2)区分冷热:如榜单列表场景使用zset,只缓存前10页数据,后续数据走db

热Key的定义:

用户访问一个Key的QPS特别高,导致Server实例出现CPU负载突增或者不均的情况。热key没有明确的标准,QPS超过500就有可能被识别为热Key

解决热Key的方法

1.设置Localcache

在访问Redis前,在业务服务侧设置Localcache,降低访问Redis的QPS。LocalCache中缓存过期或未命中,则从Redis中将数据更新到LocalCache。Java的Guava、Golang的Bigcache就是这类LocalCache

⒉拆分

将keyvalue这一个热Key复制写入多份,例如key1:value,key2.value,访问的时候访问多个key,但value是同一个,以此将qps分散到不同实例上,降低负载。代价是,更新时需要更新多个key,存在数据短暂不一致的风险