当前位置 博文首页 > 韩超的博客 (hanchao5272):Redis:简介、数据结构、回收策略、

    韩超的博客 (hanchao5272):Redis:简介、数据结构、回收策略、

    作者:[db:作者] 时间:2021-09-05 16:09

    简介

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

    数据结构

    • String: 二进制安全的字符串
      • 应用举例:MySql的缓存层、视频播放量累加计数、共享Session、限速。
    • Lists: 按插入顺序排序的字符串元素的列表。他们基本上就是链表(linked lists)
      • 应用举例:栈(lpush+lpop)、队列(lpush+rpop)、有限集合(lpush+ltrim)、消息队列(lpush+brpop)、。
    • Sets: 不重复无序的字符串元素的无序集合
      • 应用举例:标签。
    • Sorted Sets: 不重复有序的字符串元素的有序集合
      • 类似Sets,但是每个字符串元素都关联到一个叫score浮动数值(floating number value)。
      • 里面的元素总是通过score进行着排序,所以不同的是,它是可以检索的一系列元素。
      • 例如你可能会进行范围查询:给我前面10个或者后面10个元素。
      • 应用举例:消息重试、排行榜。
    • Hashes: 由field和关联的value组成的散列表。field和value都是字符串的。这和Ruby、Python的hashes很像。
      • 应用举例:对象信息(对象的每个属性对应一个键)。
    • Bit arrays (或者说 simply bitmaps): 位图。通过以一个比特位来表示key对应的value是0还是1。
      • 并不是一种真实的数据结构,而是将String值当做比特来处理。
      • 由于字符串是二进制安全的大对象,其最大长度是512MB,因此位图适合设置2^32个比特位。
      • 通过特殊的命令,你可以将 String 值当作一系列 bits 处理:
        • 可以设置和清除单独的 bits;
        • 可以数出所有设为 1 的 bits 的数量;
        • 可以找到最前的被设为 1 或 0 的 bit,等等。
      • 应用举例:存储用户的在线状态:在线=1,离线=0。
    • HyperLogLogs: 基数统计。是一种基于概率的数据结构,用于估算一个集合中指定元素的个数。
      • HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值。
      • 优势在于:这个结构可以非常省内存的去统计各种计数。
      • 缺点在于:估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值。
      • 应用举例:注册 IP 数、每日访问 IP 数、页面实时UV)、在线用户数等。
    • Geospatial: 地理位置。将给定的空间元素(纬度、经度、名字)添加到指定的键里面。
      • 这些数据将会存储到有序集合中,以方便后续的半径查询等操作。部分可进行的操作有:
        • 通过GEOPOS从键里面返回所有给定位置元素的位置(经度和纬度)。
        • 通过GEODIST返回两个给定位置之间的距离。
        • 通过GEORADIUS以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
      • 应用举例:地图位置。

    回收策略

    当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情。

    LRU是Redis唯一支持的回收方法,所谓LRU即:Least Recently Used,最近最少使用算法。

    Redis的maxmemory指令用于将可用内存限制成一个固定大小。Redis的maxmemory指令用于将可用内存限制成一个固定大小

    maxmemory 100mb
    

    设置maxmemory为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。

    当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。

    以下的策略是可用的:

    • noeviction:返回错误。
    • allkeys-lru:对全部键,尝试回收最近最少使用(LRU)的键。
    • volatile-lru:对在过期集合的键,尝试回收最近最少使用(LRU)的键。
    • allkeys-random:对全部键,尝试回收随机的键。
    • volatile-random:对在过期集合的键,尝试回收随机的键。
    • volatile-ttl:对在过期集合的键,优先回收存活时间(TTL,Time To Live)较短的键。

    策略选择举例:

    • 如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期,可以选择:volatile-ttl
    • 如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常,可以选择:allkeys-random
    • 如果你不确定选择什么,可以选择:allkeys-lru

    持久化

    Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)。

    RDB

    • RDB 是 Redis 默认的持久化方案。

    • 在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中,即在指定目录下生成一个dump.rdb文件。

    • Redis 重启会通过加载dump.rdb文件恢复数据。

    • RDB配置方式(redis.conf):

      ## save 指定时间间隔内 执行指定次数的更新操作
      ## 如果900秒内有1次更新操作,或者300秒内有10次更新操作,或者60秒内有10000次更新操作,则将内存数据持久化至磁盘。
      save 900 1
      save 300 10
      save 60 10000
      ## 指定本地数据库文件名
      dbfilename dump.rdb
      ## 指定数据库存放陌路
      dir ./
      ## 默认开启数据压缩
      rdbcompression yes
      
    • 可以手动通过SAVE(阻塞持久化, 只管保存快照,其他的等待)和BGSAVE(异步非阻塞持久化)命令,让redis进行持久化操作。

    • 工作方式:

      • Redis调用forks,同时拥有父进程和子进程;
      • 子进程将数据写入临时RDB文件;
      • 当新RDB文件写入完成,替换掉旧RDB文件,删除旧RDB文件。

    AOF

    采用RDB方式,如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。

    从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 。

    AOF配置方式(redis.conf)

    ## 开启AOF
    appendonly yes
    ## 指定本地数据库文件名
    appendfilename "appendonly.aof"
    ## 指定更新日志条件
    # appendfsync always
    appendfsync everysec
    # appendfsync no
    

    从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。

    这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

    三种AOF更新方式:

    • always:每次发生数据变化会立刻写入到磁盘中。性能差、数据完整性高。
    • everysec:每秒异步记录一次。默认配置。性能好。
    • no:不同步。

    缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

    针对AOF文件很大的问题,Redis提供了重建rebuild机制,

    总结

    • Redis默认开启RDB持久化方式。
    • RDB性能较高,但数据一致性和完整性相对差;AOF数据一致性和完整性相对好,但性能较低。
    • 如果Redis只做缓存,可以关闭持久化。
    • 如果Redis做持久化,建议RDB和AOF都开启。

    参考

    • http://www.redis.cn/
    • https://www.jb51.net/article/136322.htm
    • https://www.jianshu.com/p/99de0f43f11b
    • https://www.cnblogs.com/dukuan/p/9132600.html
    • http://www.redis.cn/topics/lru-cache.html
    • https://www.cnblogs.com/itdragon/p/7906481.html
    cs