Redis可能很多朋友都用过,尤其是高并发的场景,可以通过Redis缓存提升数据的访问性能,技术社群的这篇文章《解析Redis的“快”究竟适合哪些应用场景》给我们讲解了一些可以应用到Redis的场景,值得学习了解。
Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、KEY-Value数据库,并提供多种语言的API。
从以上对Redis的概念诠释来看,它是数据库,它的数据模型为健值数据结构。
维度 |
MYSQL |
Redis |
Primary DBMS |
Rational DBMS |
KEY-Value DBMS |
开发语言 |
C & C++ |
C |
事务 |
ACID |
Atomic execution & optimistic locking |
APIs |
ADO.NET、JDBC、ODBC Proprietary native API |
proprietary protocol |
Data scheme |
Yes |
Scheme-Free |
从以上对比来看,我们发现Redis与通常的MSQL相比较而言,数据结构类型不同,并发控制机制不同,API接口不同,数据管理模式也不同。从数据类型以及其访问速度之快(根据Redis官方测试基准数据,可以达到十万QPS)的特点出发,多数情况下它会被应用在大型缓存的场景下。
操作 |
具体内容 |
命中率统计 |
在读取一个键之后,根据键是否存在来更新服务器的键空间命中次数。 |
LRU时间更新 |
在读取一个键之后,会更新键的LRU时间,用于计算键的闲置时间。 |
惰性删除 |
如果服务器在读取一个键时发现该键已经过期,那么会先删除这个过期键,然后才执行余下的其他操作。 |
键的dirty标识 |
如果有客户端使用WATCH命令监视了该键,服务器会将这个键标记为dirty,让事务程序注意到这个键已经被修改过。每次修改都会对dirty加一,用于触发持久化和复制。 |
数据库通知 |
在对键进行修改之后,服务器将按配置发送相应的数据库通知。 |
Redis中数据过期策略采用定期删除&惰性删除策略。
策略 |
具体算法 |
定期删除策略 |
Redis启用一个定时器定时监视所有KEY,判断KEY是否过期,过期的话就删除。这种策略可以保证过期的KEY最终都会被删除,但是也存在严重的缺点:每次都遍历内存中所有的数据,非常消耗CPU资源,并且当KEY已过期,但是定时器还处于未唤起状态,这段时间内KEY任然可以使用。 |
惰性删除策略 |
在获取KEY时,先判断KEY 是否过期,如果过期则删除。这种方式存在一个缺点:如果这个KEY一直未被使用,那么它一直在内存中,其实它已经过期了,会浪费大量的空间。 |
Redis 内存淘汰机制有以下几种策略,
策略 |
算法 |
NO-Eviction |
不驱逐,新写入操作报错。 |
AllKEYs-Lru |
在键空间中,移除最近最少使用的 KEY。 |
AllKEYs-Random |
在键空间中,随机移除某个 KEY。 |
Volatile-Lru |
在设置了过期时间的键空间中,移除最近最少使用的KEY。 |
Volatile-Random |
在设置了过期时间的键空间中,随机移除某个 KEY。 |
Volatile-TTL |
在设置了过期时间的键空间中,有更早过期时间的 KEY 优先移除。 |
所谓单线程是指对数据的所有操作都是由一个线程按顺序挨个执行。单线程处理模式的有点在于,
(1)不会因为线程创建导致的性能消耗;
(2)避免上多线程上下文切换引起的CPU开销;
(3)避免了线程之间的竞争问题,不需要考虑各种锁的问题。
这几点优势当中,第二条是提升性能优势的最关键的一条。有优势就必然有劣势,大家一定会关心因为单线程模式导致的CPU资源浪费以及对并发业务的处理能力。对于CPU的问题,官方的答复“因为 Redis 是基于内存的操作,使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于服务器内存和网络。”其实这一点大家从Redis的数据结构和使用场景上也可以判断出来。那么对于并发问题,Redis是如何考虑的?
Redis的并发处理是靠IO多路复用技术实现的。多路指的是多个 socket 连接,复用指的是复用一个线程。IO多路复用主要有三种技术:select,poll,epoll。epoll 是目前最新最好的IO多路复用技术,Redis就是采用这种技术。其基本原理为:内核不监视应用程序本身的连接,而监视程序文件描述符。当客户端运行时,它将生成具有不同事件类型的套接字。在服务器端,I/O 多路复用程序会将消息放入队列,然后通过文件事件分派器将其转发到不同的事件处理器。
一个基本的网络 IO 模型,当处理 get 请求,会经历以下过程:
(1)和客户端建立建立 accept;
(2)从 socket 种读取请求 recv;
(3)解析客户端发送的请求 parse;
Redis主要的数据结构就是健值对,但是对于值(Value)来讲,对于数据库的性能是有着很大影响的。对于Redis的Value常用的数据结构包含:String、List、Hash、Set、Zset。他们都是基于基本的字符串、列表、哈希等基本类型进行改造了的高效数据结构。以String为例说明。
基本的String类型,通常使用长度为 N+1 的字符数组来表示长度为 N 的字符串,并且字符串数组的最后一个元素总是空字符 '\0'。Redis使用的SDS字符串,在通常字符串的基础上增加了几个字段,分别用来标识空闲空间和当前数据长度。
正因为这两个重要的字段,使得Redis有了非常重要的性能提升,
(1)它可以使得Redis以O(1)复杂度获取字符串长度:有len字段的存在,无需像C结构一样遍历计数。
(2)提高内存分配的效率,C字符串不记录已占用的长度,所以需要提前分配足够空间,一旦空间不够则会溢出。而有free字段的存在,让SDS在执行前可以判断并分配足够空间给程序。同时减少字符串修改带来的内存重分配次数,提高空间预分配和惰性释放的能力。
凡事必有缘由,通过以上分析,正是因为在硬件、线程模式以及数据结构等方面的优势,Redis天然成为一种非常快的数据库,在快的同时我们同时看到了它在数据模型方面的包容性和并发连接处理的先进性。理解这些之后,再来审视在保单业务当中的具体应用,就不难发现其技术的优势与应用场景的契合点,同时也更加明确了大家对Redis应用场景的选择思路。
如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发朋友圈,
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/hd-yjs/20479.html