关于redis的事件处理机制,网上有很详细的源码解析了,基于2.0.4的,URL如下:
redis源代码分析8–事件处理(上)
redis源代码分析8–事件处理(中)
redis源代码分析8–事件处理(下)
小总结:
初始化:在redis.c中initServer调用aeCreateEventLoop,并建立了现有唯一的一个time event:serverCron.
使用:在redis.c中main
1) 调用aeSetBeforeSleepProc设置beforeSleep函数,我看的源码是2.2.1的,功能比2.0.4稍作改变,加上了处理之前等待BLPOP的已经unblock的clients的功能.
2) 调用aeMain进入主循环,循环调用beforesleep和aeProcessEvents.程序出口在serverCron中,若接收到SIGTERM,则调用prepareForShutdown,随后退出.
2.1) 在Ae.c中aeProcessEvents,先处理file event,然后处理time event.小trick:先算好最近的time event的expire的时间(aeSearchNearestTimer),传给aeApiPoll,因此处理完file event以后,马上就可以处理time event.尤其当aeApiPoll使用反射机制的epoll和kqueue时,不会白白占用CPU时间来轮询.
顺便补上select,epoll,kqueue的比较资料:
---------------------<<以下来源于iteye
>>-------------------------
先说select
:
1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024.
2.操作限制:通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍.
后说poll:
1.Socket数量几乎无限制:该模式下的Socket对应的fd列表由一个数组来保存,大小不限(默认4k).
2.操作限制:同Select.
再说:epoll:
1.Socket数量无限制:同Poll
2.操作无限制:基于内核提供的反射模式,有活跃Socket时,内核访问该Socket的callback,不需要遍历轮询.
大部分情况下,反射的效率都比遍历来的高,但是当所有Socket都活跃的时候,反射还会更高么?这时候所有的callback都被唤醒,会导致资源的竞争.既然都是要处理所有的Socket,那么遍历是最简单最有效的实现方式.
举例来说:
对于IM服务器,服务器和服务器之间都是长链接,但数量不多,一般一台60\70个,比如采用ICE这种架构设计,但请求相当频繁和密集,这时候通过反射唤醒callback不一定比用select去遍历处理更好.
对于web portal服务器,都是浏览器客户端发起的http短链接请求,数量很大,好一点的网站动辄每分钟上千个请求过来,同时服务器端还有更多的闲置等待超时 的Socket,这时候没必要把全部的Socket都遍历处理,因为那些等待超时的请求是大多数的,这样用epoll会更好.
---------------------<<blow from stackovelflow>>-------------------------
poll / select
1) Two flavours (BSD vs. System V) of more or less the same thing.
2) Somewhat old and slow, somewhat awkward usage, but there is virtually no platform that does not support them.
3) Waits until "something happens" on a set of descriptors
3.1) Allows one thread/process to handle many requests at a time.
3.2) No multi-core usage.
4) Needs to copy list of descriptors from user to kernel space every time you wait. Needs to perform a linear search over descriptors. This limits its effectiveness.
5) Does not scale well to "thousands" (in fact, hard limit around 1024 on most systems, or as low as 64 on some).
6) Use it because it's portable if you only deal with a dozen descriptors anyway (no performance issues there), or if you must support platforms that don't have anything better. Don't use otherwise.
epoll
1) Linux only.
2) Concept of expensive modifications vs. efficient waits:
2.1) Copies information about descriptors to kernel space when descriptors are added (epoll_ctl)
3) This is usually something that happens rarely.
3.1) Does not need to copy data to kernel space when waiting for events (epoll_wait)
This is usually something that happens very often.
3.2) Adds the waiter (or rather its epoll structure) to descriptors' wait queues
3.2.1) Descriptor therefore knows who is listening and directly signals waiters when appropriate rather than waiters searching a list of descriptors
3.2.2) Opposite way of how poll works
3.2.3) O(1) and very fast instead of O(n)
4) Works very well with timerfd and eventfd (stunning timer resolution and accuracy, too).
5) Some minor pitfalls:
5.1) An epoll wakes all threads waiting on it (this is "works as intended"), therefore the naive way of using epoll with threads is useless.
5.2) Does not work as one would expect with file read/writes ("always ready").
5.3) Could not be used with AIO until recently, now possible via eventfd, but requires a (to date) undocumented function.
kqueue
1) BSD analogon to epoll, different usage, similar effect.
2) Rumoured to be faster (I've never used it, so cannot tell if that is true).
分享到:
相关推荐
Redis是一款高性能的键值数据库,其内部的事件处理机制对于其高效运行至关重要。在本讨论中,我们将深入探讨Redis的事件机制,并将其源码部分提取出来,改造为一个独立的模块,以便在其他项目中复用。这涉及到C语言...
4. 错误处理:在进行Redis操作时,可能会遇到网络问题或Redis服务器错误,类模块应有适当的错误处理机制,如捕获异常并返回错误信息。 压缩包中的其他文件包括: 1. `redis测试.exe`:这是VB6编译后的可执行文件,...
本教程将详细讲解如何在C#环境中利用Redis的发布订阅(Publish-Subscribe,简称Pub/Sub)机制实现跨进程通信,并且会涉及到Key过期通知的处理。 首先,我们需要了解Redis的发布订阅机制。在Redis中,发布订阅是一种...
异步模式下,你需要实现回调函数来处理网络事件。 7. **内存管理**: hiredis库提供了一些内建的内存管理机制,例如`redisFree`用于释放`redisContext`,`freeReplyObject`用于释放`redisReply`。 8. **RedisDemo...
- **端口冲突**:确保Redis默认的6379端口未被其他服务占用,若已占用,可在配置文件中修改端口号。 - **权限问题**:启动Redis时,可能需要以特定用户(如`redis`)运行,或者修改配置文件中的`requirepass`设置...
Redis消息队列是指通过Redis数据结构作为中介,实现生产者与消费者之间解耦的数据传输机制。它由消息队列(Message Broker)、生产者和消费者三个角色组成。在微服务场景下,这种解耦有助于提高系统的灵活性和可扩展...
6. **网络事件处理器**:Redis基于Epoll事件模型,具有很好的网络性能和可扩展性。 接下来,我们来谈谈如何安装和配置Redis 3.0.7。通常,你可以从Redis官方网站下载源码包`redis-3.0.7.tar`,然后解压并编译安装。...
2. 异步I/O:Redis采用单线程模型处理所有客户端请求,通过事件驱动的非阻塞I/O(epoll、kqueue等)来提高并发性能。 3. 持久化:RDB和AOF两种持久化策略,C++代码中实现了快照保存和增量日志记录。 4. 主从复制:...
或者,你可以使用其他支持Redis的开发工具,如RedisInsight或可视化客户端,进行更方便的操作。 5. **守护进程化**:为了使Redis在后台持续运行,可以创建一个Windows服务。这通常通过`redis-server.exe --service-...
在上述场景中,我们可以利用Redis的过期机制来进一步确保订单的自动取消。将订单信息存储为Redis中的键值对,设置键的过期时间与订单的超时时间一致。当订单到达超时时间后,Redis会自动删除该键,这可以触发一个...
由于Windows系统与Unix-like系统(如Linux)在某些底层机制上有所不同,Redis的开发者提供了适应Windows环境的二进制版本,确保在Windows上同样能享受到Redis的高效性能。 描述中提到"解压即用无需安装",意味着...
6. **发布/订阅**:Redis的发布/订阅功能允许客户端订阅感兴趣的频道,当有其他客户端向该频道发送消息时,所有订阅者都能收到消息,这在实现消息通知和异步通信中非常有用。 7. **Redis Cluster**:Redis Cluster...
对于可能出现的网络错误或命令执行失败,你需要在`RedisClient`类中提供适当的错误处理机制,例如抛出异常或返回错误代码。 8. **实例化和使用RedisClient**: 在Qt应用程序的适当位置实例化`RedisClient`对象,...
当某个节点发生故障时,Redis Cluster能够自动检测并执行故障转移,将故障节点的槽迁移到其他健康的节点上,确保服务的连续性。这个过程是透明的,对客户端应用无感知。 4. **客户端连接**: 在Redis 5.0.2中,...
4. **性能差异**:尽管Memcached是纯内存存储,但Redis通过优化的事件循环机制(libevent)和其他内部优化措施,在某些场景下仍能表现出更高的性能。 #### 四、Redis的数据存储策略 - **内存管理**:由于Redis的所有...
集群的每个节点都需要运行`redis-server`,并通过`redis-trib.rb`与其他节点建立连接。 Redis 4.0.11版本引入了一些重要的改进和特性: - **模块系统**:Redis 4.0开始支持模块扩展,允许开发人员为Redis添加...
这可以通过静态内部类单例模式、同步方法或其他线程安全机制实现。 10. **测试与文档** 为确保RedisUtils的正确性,需要编写单元测试覆盖所有关键功能。同时,提供清晰的API文档,解释每个方法的作用、参数含义和...
Redis可以配置为在键的操作发生时发送通知,这对构建缓存失效机制或监控系统很有用。 12. **Redis Cluster如何实现分布式?** Redis Cluster是一种分布式的解决方案,支持数据自动分片和故障转移。每个节点存储...
1. **bin**:这个目录包含了Redis服务器(redis-server)、客户端(redis-cli)以及其他命令行工具,如用于清除Redis实例数据的`redis-check-aof`和`redis-check-rdb`。安装完成后,可以通过这个目录下的可执行文件...