登录 注册
购物车0
TOP
Imgs 行业资讯

0

Redis基本数据类型有哪些

2021-11-25 14:01:15
说说Redis基本数据类型有哪些吧
 
字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型。C语言的字符串不记录自身的长度信息,而SDS则保存了长度信息,这样将获取字符串长度的时间由O(N)降低到了O(1),同时可以避免缓冲区溢出和减少修改字符串长度时所需的内存重分配次数。
 
 
链表linkedlist:redis链表是一个双向无环链表结构,很多发布订阅、慢查询、监视器功能都是使用到了链表来实现,每个链表的节点由一个listNode结构来表示,每个节点都有指向前置节点和后置节点的指针,同时表头节点的前置和后置节点都指向NULL。
 
字典hashtable:用于保存键值对的抽象数据结构。redis使用hash表作为底层实现,每个字典带有两个hash表,供平时使用和rehash时使用,hash表使用链地址法来解决键冲突,被分配到同一个索引位置的多个键值对会形成一个单向链表,在对hash表进行扩容或者缩容的时候,为了服务的可用性,rehash的过程不是一次性完成的,而是渐进式的。
 
跳跃表skiplist:跳跃表是有序集合的底层实现之一,redis中在实现有序集合键和集群节点的内部结构中都是用到了跳跃表。redis跳跃表由zskiplist和zskiplistNode组成,zskiplist用于保存跳跃表信息(表头、表尾节点、长度等),zskiplistNode用于表示表跳跃节点,每个跳跃表的层高都是1-32的随机数,在同一个跳跃表中,多个节点可以包含相同的分值,但是每个节点的成员对象必须是唯一的,节点按照分值大小排序,如果分值相同,则按照成员对象的大小排序。
 
整数集合intset:用于保存整数值的集合抽象数据结构,不会出现重复元素,底层实现为数组。
 
压缩列表ziplist:压缩列表是为节约内存而开发的顺序性数据结构,他可以包含多个节点,每个节点可以保存一个字节数组或者整数值。
 
基于这些基础的数据结构,redis封装了自己的对象系统,包含字符串对象string、列表对象list、哈希对象hash、集合对象set、有序集合对象zset,每种对象都用到了至少一种基础的数据结构。
 
redis通过encoding属性设置对象的编码形式来提升灵活性和效率,基于不同的场景redis会自动做出优化。不同对象的编码如下:
 
字符串对象string:int整数、embstr编码的简单动态字符串、raw简单动态字符串
 
列表对象list:ziplist、linkedlist
 
哈希对象hash:ziplist、hashtable
 
集合对象set:intset、hashtable
 
有序集合对象zset:ziplist、skiplist
 
Redis为什么快呢?
 
redis的速度非常的快,单机的redis就可以支撑每秒10几万的并发,相对于mysql来说,性能是mysql的几十倍。速度快的原因主要有几点:
 
完全基于内存操作
 
C语言实现,优化过的数据结构,基于几种基础的数据结构,redis做了大量的优化,性能极高
 
使用单线程,无上下文的切换成本
 
基于非阻塞的IO多路复用机制
 
那为什么Redis6.0之后又改用多线程呢?
 
redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。
 
这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。
 
知道什么是热key吗?热key问题怎么解决?
 
所谓热key问题就是,突然有几十万的请求去访问redis上的某个特定key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致这台redis的服务器宕机引发雪崩。
 
针对热key的解决方案:
 
提前把热key打散到不同的服务器,降低压力
 
加入二级缓存,提前加载热key数据到内存中,如果redis宕机,走内存查询
 
什么是缓存击穿、缓存穿透、缓存雪崩?
 
缓存击穿
 
缓存击穿的概念就是单个key并发访问过高,过期时导致所有请求直接打到db上,这个和热key的问题比较类似,只是说的点在于过期导致请求全部打到DB上而已。解决方案:
锁定和更新,比如请求查询A,发现不在缓存中,锁定密钥A,同时查询数据库中的数据,写入缓存,然后返回给用户,这样以后的请求就可以从缓存中获取数据。
将到期时间的组合写入值中,并以异步方式不断刷新到期时间,以防止这种现象。
缓存穿透
缓存穿透指的是查询缓存中不存在的数据,每个请求都会命中DB,就好像缓存不存在一样。
为了解决这个问题,添加一层布隆过滤器。Bloom  filter的原理是当你存储数据时,会通过hash函数映射到一个位数组中的K个点,同时将它们设置为1。
这样,当用户再次查询A,而A在Bloom过滤器中为0,直接返回时,就不会有对DB的细分请求。
显然,使用Bloom  filter后,会出现误判的问题,因为它本身就是一个数组,可能会有多个值落到同一个位置。理论上,只要我们的阵列足够长,误判的概率就会更低,这种问题要根据实际情况来定。
缓存雪崩
当某个时刻发生大规模的缓存故障,比如你的缓存服务宕机,就会有大量的请求进来,直接打到DB,可能导致整个系统崩溃,这就叫雪崩。与雪崩击穿和热键问题不同,他的意思是大规模缓存已经过期。
雪崩的几种解决方案:
为不同的密钥设置不同的到期时间,以避免同时到期。
限流,如果redis宕机,您可以前往限流,从而避免同时出现大量崩溃DB的请求。
二级缓存,同样的热键方案。
Redis的到期政策有哪些?
Redis主要有两种过期删除策略。
惰性缺失
惰性删除是指我们查询密钥时检测到密钥,如果已经到了过期时间,则删除密钥。显然,他的一个缺点是,如果这些过期的密钥不被访问,那么它们就不能一直被删除,而且它们总是会占用内存。
定期删除
定期删除意味着redis每隔一段时间检查一次数据库,删除其中过期的密钥。因为不可能轮询所有键来删除它们,所以redis会随机选择一些键来一次检查和删除。
过期的钥匙没有被常规惯性删除怎么办?
假设redis定期随机查询时每次都没有删除密钥,并且这些密钥没有被查询,会导致这些密钥被保存在redis中,无法删除。这时候就要去redis的内存消除机制了。
Volatile-lru:从设置了清除过期时间的密钥中删除最近最少使用的密钥。
Volatile-ttl:从已设置过期时间的密钥中删除将要过期的密钥。
Volatile-random:从设置了过期时间的密钥中随机选择密钥剔除。
Allkeys-lru:选择最近最少使用的键进行消除。
Allkeys-random:从按键中随机选择按键以消除它们。
注意:当内存达到阈值时,新的写操作会报告一个错误。
坚持的方式有哪些?有什么区别?
Redis持久性方案分为RDB和AOF。
关系数据库
RDB持久性可以根据配置手动或定期执行。它的功能是将某个时间点的数据库状态保存到一个RDB文件中,这是一个压缩的二进制文件,通过它可以恢复某个时刻的数据库状态。因为RDB文件存储在硬盘上,所以即使redis崩溃或退出,只要RDB文件存在,它就可以用于恢复已恢复数据库的状态。
您可以通过保存或保存来生成RDB文件。
SAVE将阻止redis进程,直到生成RDB文件。在进程阻塞期间,redis不能处理任何命令请求,这显然是不合适的。
BGSAVE会分叉出一个子进程,然后子进程负责生成RDB文件,父进程可以继续处理命令请求,而不会阻塞进程。
吖啶橙荧光检查法
与RDB不同,AOF通过保存redis服务器执行的写命令来记录数据库状态。
AOF通过三个步骤实现持久性机制:追加、写入和同步。
当AOF持久性处于活动状态时,在服务器执行写命令后,写命令将被追加到aof_buf缓冲区的末尾。
在服务器结束事件循环之前,它将调用flushAppendOnlyFile函数来决定是否将aof_buf的内容保存在aof文件中,这可以通过配置appendfsync来决定。
总是##aof_buf内容被写入并同步到aof文件
Everysec  ##将aof_buf的内容写入aof文件,如果上次同步AOF文件的时间超过一秒钟,请再次同步AOF文件。
No  ##将aof_buf的内容写入aof文件,但不同步AOF文件,同步时间由操作系统决定。如果没有设置,默认选项将是每秒,因为总是最安全的(只丢失一次事件循环的写命令),但它的性能很差,而每秒模式可能只丢失1秒的数据,而没有模式具有与每秒相同的效率,但它将丢失最后一次同步AOF文件后的所有写命令数据。
如何实现Redis的高可用性?
要实现高可用性,一台机器肯定是不够的,redis有两种选择来保证高可用性。
主从架构
主从模式是实现高可用性最简单的方案,核心是主从同步。主从同步的原理如下:
从机向主机发送同步命令
收到mastersync后,执行bgsave以生成完整的RDB文件。
将主从命令写入缓存。
BG执行后,将RDB文件发送给从机,从机执行。
主机将缓存中的写命令发送给从机,从机执行该命令。
我这里写的命令是sync,但是在redis2.8版本之后,用psync代替了sync,因为sync命令消耗了大量的系统资源,psync效率更高。
哨兵
主从方案的缺点很明显。如果主机宕机,那么数据无法写入,那么从机将失去功能,整个架构将不可用。除非手动切换,否则主要原因是没有自动故障转移机制。Sentinel比简单的主从架构功能更全面,具有自动故障转移、集群监控、消息通知等功能。
哨兵可以同时监控多个主从服务器,当被监控的主服务器离线时,自动将一个从服务器提升为主服务器,然后新的主服务器将继续接收命令。整个过程如下:
初始化sentinel,用sentinel特有的代码替换普通的redis代码。
初始化主词典和服务器信息。服务器信息主要存储ip:port,记录实例的地址和ID。
用master创建两个连接,命令连接和订阅连接,订阅sentinel:hello频道。
每10秒向主机发送一次info命令,获取主机及其下所有从机的当前信息。
发现主机有新的从机后,sentinel和新的从机也建立两个连接,每10秒发送一个info命令更新主机信息。
Sentinel每1秒钟向所有服务器发送ping命令。如果服务器在配置的响应时间内连续返回无效回复,它将被标记为脱机。
选举领袖哨兵,领袖哨兵需要哨兵同意的一半以上。
领导者哨兵从离线主设备的所有从设备中选择一个,并将其转换为主设备。
让所有从机从新主机复制数据。
将原主服务器设置为新主服务器的从服务器。当原主服务器再次回复连接时,它将成为新主服务器的从服务器。
Sentinel会每1秒向所有实例(包括主从服务器和其他sentinel)发送ping命令,并根据回复判断是否已经离线。这种方法叫主观下线。当判断为主观下线时,会询问其他监控哨。如果超过半数的选票认为是离线,则标记为客观离线,触发故障转移。
你能告诉我redis集群的原理吗?
如果依靠sentry可以实现redis的高可用性,如果想支持高并发同时又能容纳大量数据,就需要redis集群。Redis集群是redis提供的分布式数据存储方案。群集通过数据分片共享数据,并提供复制和故障转移功能。
结节
redis集群由多个节点组成,这些节点通过cluster  meet命令进行连接。节点的握手过程:
节点从客户端接收群集会议命令。
a根据接收到的IP地址和端口号向B发送满足消息。
节点B接收到满足消息并返回pong。
知道A和B收到了见面消息,他们返回了ping消息,握手成功。
最后,节点A会通过流言协议将节点B的信息传播给集群中的其他节点,其他节点也会和B握手。
当接收到客户端EXEC命令时,WATCH命令监控整个事务中的键是否被修改。如果是,它会向客户端返回一个空的回复来指示失败。否则,redis将遍历整个事务队列,执行存储在队列中的所有命令,最后将结果返回给客户端。
WATCH机制本身是一个CAS机制。受监控的密钥将保存在链接列表中。如果一个密钥被修改,REDIS_DIRTY_CAS标志将被打开,服务器将拒绝执行该事务。

高都电子,为客户创造价值!

双面板免费加费,四层板加急打样,厚铜电路板打样

Xcm