redis基础知识汇总

    技术2022-07-11  86

    redis基础知识汇总

    一、redis 基础知识1. 什么是Redis?2. redis的优缺点?3. redis比memcached的优势在哪里?以及两者的区别?4. redis的持久化策略?5. Redis过期键的删除策略6. 数据淘汰策略7. redis的事务?8、redis 事件?9、redis 集群redis哨兵数据分片主从配置 二、Redis的应用场景

    一、redis 基础知识

    1. 什么是Redis?

    Redis(Remote Dictionary Server) 是一个使用 C 语言编写的、开源的、高性能非关系型(NoSQL)的键值对数据库。

    Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:String(字符串),List(列表),Set(无序集合),ZSet(有序集合),Hash(无序散列表)。具体类型使用可看见这篇文章

    与传统数据库不同的是 Redis 的数据是存在内存中的,读写速度非常快,因此 redis 被广泛应用于缓存方向。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、多种集群方案。

    2. redis的优缺点?

    优点

    读写性能优异, Redis能读的速度是110000次/s,写的速度是81000次/s。支持数据持久化,支持AOF和RDB两种持久化方式。支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构。支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用

    缺点

    数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

    3. redis比memcached的优势在哪里?以及两者的区别?

    优势

    memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型redis的速度比memcached快很多redis支持事务。redis可以持久化其数据

    区别

    redis可以看做是一个内存型的非关系数据库,memcached只是一个缓存工具。

    redis的数据类型比memcached丰富。redis的数据类型有string,list,set,zset hash.memcached只有字符串和二进制数据两种类型。

    redis的命令库更加丰富。支持批量操作 、事务支持 、每个类型不同的CRUD。memcached只是支持常用的CURD以及其他少量的其他命令。

    redis支持原生的集群模式。memcached如果要实现集群模式,就要依靠客户端的配合才行。

    redis支持持久化。memcached不支持。

    在 Redis 中,并不是所有数据都一直存储在内存中,可以将一些很久没用的 value 交换到磁盘。Memcached 的数据则会一直在内存中,Memcached 将内存分割成特定长度的块来存储数据,以完全解决内存碎片的问题。但是这种方式会使得内存的利用率不高,例如块的大小为 128 bytes,只存储 100 bytes 的数据,那么剩下的 28 bytes 就浪费掉了。

    4. redis的持久化策略?

    Redis 是内存型数据库,为了之后重用数据(比如重启机器、机器故障之后回复数据),或者是为了防止系统故障而将数据备份到一个远程位置,需要将内存中的数据持久化到硬盘上。Redis 提供了RDB和AOF两种持久化方式。默认是只开启RDB,当Redis重启时,它会优先使用AOF文件来还原数据集。

    RDB持久化方式

    RDB 持久化:将某个时间点的所有数据以快照的形式都存放到硬盘上。可以将快照复制到其它服务器从而创建具有相同数据的服务器副本。如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量很大,保存快照的时间会很长。具体可参照这篇文章

    #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。 save 900 1 创建快照的办法有如下几种: BGSAVE命令 :客户端向Redis发送 BGSAVE命令 来创建一个快照。对于支持BGSAVE命令的平台来说(基本上所有平台支持,除了Windows平台),Redis会调用fork来创建一个子进程,然后子进程负责将快照写入硬盘,而父进程则继续处理命令请求。 SAVE命令 :客户端还可以向Redis发送 SAVE命令 来创建一个快照,接到SAVE命令的Redis服务器在快照创建完毕之前不会再响应任何其他命令。SAVE命令不常用,我们通常只会在没有足够内存去执行BGSAVE命令的情况下,又或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令。 save选项 :如果用户设置了save选项(一般会默认设置),比如 save 60 10000,那么从Redis最近一次创建快照之后开始算起,当“60秒之内有10000次写入”这个条件被满足时,Redis就会自动触发BGSAVE命令。 SHUTDOWN命令 :当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器。 一个Redis服务器连接到另一个Redis服务器:当一个Redis服务器连接到另一个Redis服务器,并向对方发送SYNC命令来开始一次复制操作的时候,如果主服务器目前没有执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE命令 AOF 持久化

    开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。使用 AOF 持久化需要设置同步选项,从而确定写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。在Redis的配置文件中存在三种同步方式

    选项同步频率always每个写命令都同步,这样会严重降低Redis的速度everysec每秒同步一次no让操作系统来决定何时同步

    虽然AOF持久化非常灵活地提供了多种不同的选项来满足不同应用程序对数据安全的不同要求,但AOF持久化也有缺陷——AOF文件的体积太大。

    AOF虽然在某个角度可以将数据丢失降低到最小而且对性能影响也很小,但是极端的情况下,体积不断增大的AOF文件很可能会用完硬盘空间。另外,如果AOF体积过大,那么还原操作执行时间就可能会非常长。

    为了解决AOF体积过大的问题,用户可以向Redis发送 BGREWRITEAOF命令 ,这个命令会通过移除AOF文件中的冗余命令来重写(rewrite)AOF文件来减小AOF文件的体积。BGREWRITEAOF命令和BGSAVE创建快照原理十分相似,所以AOF文件重写也需要用到子进程,这样会导致性能问题和内存占用问题,和快照持久化一样。

    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。

    如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分就是压缩格式不再是 AOF 格式,可读性较差。

    5. Redis过期键的删除策略

    Redis中有个设置时间过期的功能,即对存储在 redis 数据库中的值可以设置一个过期时间。作为一个缓存数据库,这是非常实用的。如我们一般项目中的 token 或者一些登录信息,尤其是短信验证码都是有时间限制的,按照传统的数据库处理方式,一般都是自己判断过期,这样无疑会严重影响项目性能.具体详细的策略说明可参照这篇文章

    其实有三种不同的删除策略: (1):立即删除。在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作。 (2):惰性删除。键过期了就过期了,不管。每次从dict字典中按key取值时,先检查此key是否已经过期,如果过期了就删除它,并返回nil,如果没过期,就返回键值。 (3):定时删除。每隔一段时间,对expires字典进行检查,删除里面的过期键。

    redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用。

    6. 数据淘汰策略

    可以设置内存最大使用量,当内存使用量超出时,会施行数据淘汰策略。

    Redis 具体有 6 种淘汰策略:

    策略描述应用场景volatile-lru从已设置过期时间的数据集中挑选最近最少使用的数据淘汰如果设置了过期时间,且分热数据与冷数据,推荐使用 volatile-lru 策略。volatile-lfu从所有配置了过期时间的键中驱逐使用频率最少的键Redis 4.0 引入的。volatile-ttl从已设置过期时间的数据集中挑选将要过期的数据淘汰如果让 Redis 根据 TTL 来筛选需要删除的key,请使用 volatile-ttl 策略。volatile-random从已设置过期时间的数据集中任意选择数据淘汰很少使用allkeys-lru从所有数据集中挑选最近最少使用的数据淘汰使用 Redis 缓存数据时,为了提高缓存命中率,需要保证缓存数据都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用 allkeys-lru 淘汰策略,将最近最少使用的数据淘汰。allkeys-lfu从所有键中驱逐使用频率最少的键redis 4.0 引入的。allkeys-random从所有数据集中任意选择数据进行淘汰如果需要循环读写所有的key,或者各个key的访问频率差不多,可以使用 allkeys-random 策略noeviction不删除策略,达到最大内存限制时,如果需要更多内存,直接返回错误信息。大多数写命令都会导致占用更多的内存 很少使用

    在正式的生产环境中需要根据系统的特征,来选择合适的淘汰策略。 在运行过程中也可以通过命令动态设置淘汰策略,并通过 INFO 命令监控缓存的 miss 和 hit,来进行调优。

    7. redis的事务?

    Redis 通过 MULTI、EXEC、WATCH,UNWATCH,DISCARD 等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。

    事务中的多个命令被一次性发送给服务器,而不是一条一条发送,这种方式被称为流水线,可以减少客户端与服务器之间的网络通信次数从而提升性能。

    在传统的关系式数据库中,常用 ACID 性质来检验事务功能的可靠性和安全性。在 Redis 中,事务总是具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也具有持久性(Durability)。

    watch : 将给出的Keys标记为监测态,作为事务执行的条件.

    unwatch: 清除事务中Keys的 监测态,如果调用了EXEC or DISCARD,则没有必要再手动调用UNWATCH.

    MULTI: 显式开启redis事务,后续commands将排队,等候使用EXEC进行原子执行.

    EXEC: 执行事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,只有监测中的Keys没有被修改,命令才会被执行,否则停止执行(详见下文,CAS机制).

    DISCARD: 清除事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,释放 监测中的Keys.

    WATCH命令的使用是为了解决 事务并发 产生的不可重复读和幻读的问题(简单理解为给Key加锁)

    `MULTI`,`EXEC`,`DISCARD`才是`显式`开启并控制事务的常用命令,可类比关系型数据据库中的 `BEGAIN`,`COMMIT`,`ROLLBACK`

    事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。

    事务中的多个命令被一次性发送给服务器,而不是一条一条发送,这种方式被称为流水线,可以减少客户端与服务器之间的网络通信次数从而提升性能。

    在传统的关系式数据库中,常用 ACID 性质来检验事务功能的可靠性和安全性。在 Redis 中,事务总是具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也具有持久性(Durability)。

    Redis事务不支持Rollback

    Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。

    8、redis 事件?

    Redis服务器是一个事件驱动程序,需要处理两类事件:详情可以参照这篇文章

    1、文件事件:Redis服务器通过socket与客户端连接,而文件事件就是服务器对socket操作的抽象。服务器与客户端的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络操作。

    2、时间事件:Redis服务器中的一些操作(如ServerCron)需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。

    9、redis 集群

    redis哨兵

    Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入下线状态时,自动从从服务器中选举出新的主服务器。

    数据分片

    分片是将数据划分为多个部分的方法,可以将数据存储到多台机器里面,这种方法在解决某些问题时可以获得线性级别的性能提升。

    假设有 4 个 Redis 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,… ,有不同的方式来选择一个指定的键存储在哪个实例中。

    最简单的方式是范围分片,例如用户 id 从 0~1000 的存储到实例 R0 中,用户 id 从 1001~2000 的存储到实例 R1 中,等等。但是这样需要维护一张映射范围表,维护操作代价很高。 还有一种方式是哈希分片,使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。 根据执行分片的位置,可以分为三种分片方式:

    客户端分片:客户端使用一致性哈希等算法决定键应当分布到哪个节点。代理分片:将客户端请求发送到代理上,由代理转发请求到正确的节点上。服务器分片:Redis Cluster。

    主从配置

    通过使用 slaveof host port 命令来让一个服务器成为另一个服务器的从服务器。

    一个从服务器只能有一个主服务器,并且不支持主主复制。

    主服务器创建快照文件,发送给从服务器,并在发送期间使用缓冲区记录执行的写命令。快照文件发送完毕之后,开始向从服务器发送存储在缓冲区中的写命令从服务器丢弃所有旧数据,载入主服务器发来的快照文件,之后从服务器开始接受主服务器发来的写命令主服务器每执行一次写命令,就向从服务器发送相同的写命令

    随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。

    二、Redis的应用场景

    (1)会话缓存(Session Cache)

    最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

    幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

    (2)全页缓存(FPC)

    除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

    (3)队列

    Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

    (4)排行榜/计数器

    Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。

    (5)发布/订阅

    最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!

    (6) 查找表

    例如 DNS 记录就很适合使用 Redis 进行存储。查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。

    Processed: 0.010, SQL: 9