Redis(一):基础数据结构

Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。

image

1、String 字符串

字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 的结构不一样。字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户信息会经过一次反序列化的过程。

键值对命令:

image

批量键值对命令:可以批量对多个字符串进行读写,节省网络耗时开销

image

过期和 set 命令扩展:可以对 key 设置过期时间,到点自动删除,这个功能常用来控制缓存的失效时间

image

原子计数:如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是 signed long 的最大最小值,超过了这个值,Redis 会报错

image

2、list(列表)

Redis的列表相当于java中的LinkedList,是链表而不是数组,这意味着list的插入和删除操作非常快,时间复杂度为O(1),但是索引定位很慢,时间复杂度为O(n),当列表弹出了最后一个元素以后,该数据结构自动被删除,内存被回收;
Redis的列表结构常用来做异步队列使用,将需要延后处理的任务结构体序列化为字符串塞进Redis的列表,另一个线程从这个列表中轮询数据进行处理;

右边进左边出:队列

图片.png

右边进右边出:栈

image

3、hash(字典)

Redis的字典相当于Java中的HashMap,是无序字典,内部实现结构上同Java的HashMap也是一致的,是数据+链表二维结构的,第一维hash的数组位置碰撞时,就会将碰撞的元素使用链表串接起来;
hash结构也可以用来存储用户信息,不同于字符串String需要一次性全部序列化整个对象,hash结构可以对用户结构中的每个字段单独存储,这样当我们需要获取用户信息时,可以进行部分获取,而以整个字符串的形式去保存用户信息的话,就只能一次性全部读取,这样就会比较浪费网络流量;
hash也有缺点,就是hash结构的存储消耗要高于单个字符串。

image

4、Set(集合)

Redis的集合相当于Java中的HashSet,内部的键值对是无序的唯一的(无序是指不是按照插入数据顺序排序,而是按照字典序排序),内部实现相当于一个特殊的字典(hash),字典中所有的value都是一个值NULL,当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。

image

5、zset(有序集合)

zset类似于java的SortedSet和HashMap的结合体,一方面它是一个set,保证了内存value的唯一性,另一方面它可以给每个value赋予一个score,代表这个value排序权重。
zset可以用来存粉丝列表,value值是粉丝的用户ID,score的关注事件,可以可以对粉丝列表按关注时间进行排序;
zset还可以用来存储学生的成绩,value值是学生ID,score是他的成绩,我们可以对成绩按分数进行排序就可以得到他的名次

image

6、高级命令

  • keys:全量遍历键,用来列出所有满足正则字符串规则的key,当redis数据量比较大时,性能比较差,要避免使用
image
  • scan:渐进式遍历键,scan参数提供了三个参数,第一个是cursor整数值,第二个是key的正则模式,第三个是遍历的limit hint;
    第一次遍历时,cursor值为0,然后将返回结果中第一个整数值作为下一次遍历的cursor,一直遍历到返回的cursor值为0时结束
image
image

Redis存储键值对实际使用的是hashtable的数据结构

image
  • info:查看redis服务运行信息,分为9大块,每个块都有非常多的参数,这9个块分别是:
    1、Server 服务器运行的环境参数
    2、Clients 客户端相关信息
    3、Memory 服务器运行内存统计数据
    4、Persistence 持久化信息
    5、Stats 通用统计数据
    6、Replication 主从复制相关信息
    7、CPU CPU 使用情况
    8、Cluster 集群信息
    9、KeySpace 键值对统计数量信息
image

7、核心原理

1、Redis的单线程和高性能

  • Redis为什么这么快,尤其是其采用单线程
    因为它的所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题;
    而且正因为Redis是单线程,所以要小心使用Redis指令,对于那些耗时的指令(比如keys),一定要谨慎使用,一步小心就可能会导致Redis卡顿;

  • Redis单线程处理多个并发客户端连接:IO多路复用
    Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
    Nginx也是采用IO多路复用原理解决C10k问题

image

2、持久化

  • RDB快照(snapshot)
    在默认情况下,Redis将数据库快照保存在名字为dump.rdb的二进制文件中。
    可以对Redis进行设置,让它在“N秒内数据集中至少有M个改的”这个条件被满足时,自动保存一次数据集。
//在满足“60s内至少有1000个键被改动”这一条件时,自动保存一次数据集
save 60 100

  • AOF(append-only file)
    快照功能并不是非常耐久(durable):如果Redis因为某些原因而造成故障停机,那么服务器将丢失最近写入、且仍未保存到快照中的哪些数据。
    从1.1版本开始,Redis增加了一种完全耐久的持久化方式,AOF持久化,将修改的每一条指令记录进文件,就是说,每当Redis执行一个改变数据集的命令时(比如SET),这个命令就会被追加到AOF文件的末尾,这样的话,当Redis重新启动时,程序就可以通过重新执行AOF文件中的命令来达到重建数据集的目的。
//通过修改配置文件来打开AOF功能
appendonly yes

可以配置 Redis 多久才将数据 fsync 到磁盘一次,有三个选项:
1、每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
2、每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
3、从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

  • RDB vs AOF
    如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
    有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。

  • Redis 4.0 混合持久化
    重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。AOF在重写(aof文件里可能有太多没用指令,所以aof会定期根据内存的最新数据生成aof文件)时将 rdb文件的内容和增量的 AOF 日志文件存在一起,AOF根据配置规则在后台自动重写,也可以人为执行命令bgrewriteaof重写AOF。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。 于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

//开启混合持久化:
aof-use-rdb-preamble yes  

混合持久化aof文件结构

image

3、缓存淘汰策略
当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap)。交换会让 Redis 的性能急剧下降,对于访问量比较频繁的 Redis 来说,这样龟速的存取效率基本上等于不可用。
在生产环境中我们是不允许 Redis 出现交换行为的,为了限制最大使用内存,Redis 提供了配置参数 maxmemory 来限制内存超出期望大小。
当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。

  • noeviction:不会继续服务写请求 (DEL 请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。这是默认的淘汰策略。
  • volatile-lru:尝试淘汰设置了过期时间的 key,最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。
  • volatile-ttl:跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。
  • volatile-random:跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。
  • allkeys-lru:区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。
  • allkeys-random:跟上面一样,不过淘汰的策略是随机的 key。

volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰

8、脑图

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、has...
    雪飘千里阅读 600评论 0 2
  • 原帖地址:https://www.jianshu.com/p/2f14bc570563 redis概述 Redis...
    onlyHalfSoul阅读 2,165评论 0 28
  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,596评论 0 2
  • Redis是啥 Redis是一个开源的key-value存储系统,由于拥有丰富的数据结构,又被其作者戏称为数据结构...
    一凡呀阅读 1,173评论 0 5
  • 1.1 资料 ,最好的入门小册子,可以先于一切文档之前看,免费。 作者Antirez的博客,Antirez维护的R...
    JefferyLcm阅读 17,045评论 1 51