redis基础 | 青训营笔记

60 阅读4分钟

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

  • redis基本工作原理

    • redis特征,数据可以在一定程度上做到持久化。
    • redis客户端与服务端通信使用RESP协议。redis服务端收到读写请求后,会将数据读写到内存上,读写内存前会产生日志,AOF文件,存在磁盘上。假设服务器宕机,redis重启时会读取AOF文件,重放命令。
    • RDB文件,保存当前reids的全部数据。重启时先读取RDB文件,再去对比AOF,查看是否存在未执行的命令,如果有先执行。这样完成redis的启动,并保证启动后和之前的状态一致
    • 单进程处理所有操作命令
  • redis应用案例:

  1. 连续签到 string结构

    • 原有数值加1,设置过期时间,过期后归为0

    • string数据结构:

      • 二进制安全,实际存的二进制数据。

      • 存储要做到足够节省空间,且可以很快读出,当字符变更时可以很快写入

      • 数据结构如下:分为4段。实际存储在buf中,char的数组,这里存hello,实际会预先分配很多空间,避免扩容,扩容操作需要新开辟空间,在复制当前数据过去

      • get读取时,寻址先从sds指针位置,先向左移动指针,得到flags,知道当前数据类型,可以得知向左移动几位,到alloc,得知buf内存长度,len是buf中实际使用的内存长度,可以知道从sds向右移动几位来得到字符串,

  2. 消息通知 list结构

    • 使用场景:发表文章后,如何让es引擎知道有篇新文章需要推送?

    • redis中消息通知有两种做法:一种是消息队列,用list数据结构,一种是用pub/sub

    • List数据结构 :

      • 实际上是Quicklist,由双向链表和listpack实现。entry,又叫listpack。一般链表是一个节点存一个数据,redis为了节省内存,会在一个节点存很多数据,这些数据压缩在listpack的element里。每个element长度一样,num-elements记录实际element个数,tot-bytes记录整个listback内存空间大小。
  3. 计数 hash结构

    • 用户的文章点赞数,文章阅读数,关注人数,粉丝人数等,存在redis中。是每个数值都用一个key存?假设每个数值一个key,用户信息界面要获取多个key。hash可以把这些放在一个数据结构中

    • 写入,piprline,可以包含多条命令。一次设置多个key,一次get多个key都需要用pipeline,减少网络传输

    • 增加某一条数据的值,HIncrBy( ),可以指定hash的key,字段,值

    • hash数据结构:

      • 拉链很长时,会扩容,就是增加槽位

      • rehash过程,为什么需要rehash? hash table需要扩容,扩容时需要保证redis正常响应。渐进式rehash,将hash拷贝工作分步进行,每次迁移少量数据,全部拷贝完后,再整体切换。就是ht[0]和ht[1],ht[0]是原来的hashtable,当rehash发生后,会先初始化ht[1],这时并没有被用户访问。当有用户访问ht[0]中的数据时,会顺便把数据迁移到ht[1],每次用户访问时,进行拷贝,可能会拷贝多个数据。当数据全部被迁移到ht[1]后,会指针交换,把ht[0]指到ht[1]的数据,ht[1]设置为null,对用户来说没有感知到扩容过程

  4. 排行榜 zset结构

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

    • zset数据结构 zskiplist

      • 跳跃表数据结构:分成多层链

      • redis使用跳跃表+hash的数据结构。redis中层数最多4层,也就是上图中4条链

  5. 限流

    • 防止用户用脚本做不利于网站的事情,网站承载能力有限,如抢火车票

    • 要求1秒内放行的请求为N,超过N则禁止访问。构建key,包含当前时间时间戳,请求时会携带这个key,使用的是string

  • 总结

    学习了redis的基本工作原理,以及一些应用案例,和这些案例中使用的redis数据结构。