一、Redis概述
1.1 Redis介绍
Remote Dictionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
从2010年3月15日开始,Redis 的开发工作由 VMWare 主持。从2013年5月开始,Redis 的开发由Pivotal赞助。
1.2 Redis使用场景与特点
Redis 主要用来做缓存,还可以用于redis 的计数器生成分布式唯一主键, redis 可实现分布式锁、队列、会话缓存。
Redis 与其他 key-value 缓存产品相比,有以下三个特点:
-
Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
-
Redis 不仅支持简单的字符串(String)类型的数据,同时还提供哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等数据结构的存储。
-
Redis 支持数据的备份,即 master-slave 模式的数据备份。
1.3 Redis 优势
-
访问速度快,Redis读取速度能到110000次/s, 写速度81000次/s。
-
数据存在内存中,类似于Java中的HashMap或者C++中的哈希表(如unordered_map/unordered_set),查找和操作的时间复杂度都是O(1)
-
-
数据类型丰富,支持String,list,set,sorted set,hash等数据结构
-
支持事务,Redis中的操作都是原子性。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
-
Redis可用于缓存、消息publish/subscribe、按key设置过期时间,过期后将会自动删除。
- Redis 支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。
1.4 Memcached与Redis的区别
-
存储方式
-
Memecached 把数据全部存在内存之中, 断电后会挂掉,没有持久化功能,数据不能超过内存大小。
-
Redis数据可以存到硬盘上,这样能保证数据的持久性。
-
-
数据支持类型
-
Memcached 对数据类型支持相对简单, 只有String这一种类型
-
Redis 有复杂的数据类型。Redis支持简单的k/v类型的数据,同时还提供 list,set,zset,hash等数据结构的存储。
-
-
使用底层模型不同
-
底层实现方式以及与客户端之间通信的应用协议不一样。
-
Redis 自己构建了 VM机制, 因为一般的系统调用系统函数的话, 会浪费一定的时间去移动和请求。
-
-
集群模式: Memcached没有原生的集群模式,需要依靠客户端来实现往集群分片中写入数据; Redis支持集群模式。
-
Memcached是多线程、非阻塞IO复用的网络模型; Redis使用单线程的多路 IO 复用模型。
-
Value值大小不同: Redis最大可以达到512MB; Memcached 只有 1MB。
二、Redis 发展历程
Redis4.0
Redis 4.0 was released as GA in July 2017, newcomers should use Redis 5, but Redis 4 is currently the most production-proven release and will be updated for the next year until Redis 6 will be out. It contains several big improvements: a modules system, much better replication (PSYNC2), improvements to eviction policies, threaded DEL/FLUSH, mixed RDB+AOF format, Raspberry Pi support as primary platform, the new MEMORY command, Redis Cluster support for Nat/Docker, active memory defragmentation, memory usage and performance improvements, much faster Redis Cluster key creation, many other smaller features and a number of behavior fixed.
Redis5.0
Redis 5 was release as GA in October 2018. Redis 5.0 is the first version of Redis to introduce the new stream data type with consumer groups, sorted sets blocking pop operations, LFU/LRU info in RDB, Cluster manager inside redis-cli, active defragmentation V2, HyperLogLogs improvements and many other improvements.
Redis6.0
Redis 6.0 introduces SSL, the new RESP3 protocol, ACLs, client side caching, diskless replicas, I/O threads, faster RDB loading, new modules APIs and many more improvements.
三、Redis的线程模式
3.1 单线程说明
Redis单线程 指的是【接收客户端请求 -> 解析请求 -> 进行数据读写等操作 -> 发送数据给客户端】这个过程是由一个线程(主线程)来完成的。
但 Redis程序并不是单线程的, Redis在启动的时候,会启动后台线程, 用于关闭文件、AOF刷盘、释放内存等操作。
3.2 单线程的优势与问题
单线程不需要考虑线程安全问题,很多操作不用加锁。
读写性能高的原因: Redis的全部操作都是纯内存的操作;Redis采用单线程,有效避免了频繁的上下文切换;采用了非阻塞I/O多路复用机制。
3.3 单线程处理逻辑
基于Event loop模式来处理Client请求, 网络 I/O 和命令处理都是单线程。
Redis 初始化流程:
-
首先,调用 epoll_create() 创建一个 epoll对象 和 调用 socket()创建一个服务端socket
-
然后,调用 bind() 绑定端口 和 调用 listen() 监听该socket;
-
然后,将调用 epoll_ctl() 将 listen socket 加入到 epoll,同时注册【连接事件】处理函数。
初始化完后,主线程就进入到一个事件循环函数,主要会做以下事情:
-
首先,先调用处理发送队列函数,检查发送队列里是否有任务,
-
如果有发送任务,则通过write函数将客户端发送缓存区里的数据发送出去,如果这一轮数据没有发送完,就会注册写事件处理函数,等待epoll_wait发现可写后再处理。
-
-
接着,调用 epoll_wait 函数等待事件的到来:
-
连接事件,则调用连接事件处理函数:调用accpet获取已连接的socket -> 调用epoll_ctl将已连接的socket加入到epoll -> 注册【读事件】处理函数;
-
读事件,则调用读事件处理函数:调用read获取客户端发送的数据 -> 解析命令 -> 处理命令 -> 将客户端对象添加到发送队列 -> 将执行结果写到发送缓存区等待发送;
-
写事件,则调用写事件处理函数:通过write将客户端发送缓存区里的数据发送出去,如果数据没有发送完,就会继续注册写事件处理函数,等待epoll_wait发现可写后再处理 。
-
标签:01,epoll,单线程,Redis,发送,调用,概述,客户端 From: https://www.cnblogs.com/kingdomer/p/17352752.html