嘟嘟程序猿

Redis(一):基础数据结构

2019-05-02  本文已影响3人  半子胜青天

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、高级命令

image image image

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

image image

7、核心原理

1、Redis的单线程和高性能

image

2、持久化

//在满足“60s内至少有1000个键被改动”这一条件时,自动保存一次数据集
save 60 100

//通过修改配置文件来打开AOF功能
appendonly yes

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

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

混合持久化aof文件结构

image

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

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

8、脑图

image
上一篇 下一篇

猜你喜欢

热点阅读