为什么Redis能支持高并发

Redis为何又快又单线程

一、Redis为什么快

  • 纯内存K-V操作

    数据库的工作模式按存储方式分为了磁盘数据库和内存数据库。Redis将数据存储在内存中,并且绝大多数命令都不会受到磁盘 IO 速度的限制,所以速度极快。此外,Redis内部采用了 HashMap 这种数据结构,从根本上获得了优势,因为 HashMap 无论是查找和操作的时间复杂度都是O(1)

  • 采用了多路复用的I/O机制

    Redis是单线程的,但它底层使用了多路复用 I/O 机制。多路 /O 复用模型是指利用select、poll、epoll 同时监察多个流的 I/O 事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒。程序会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法避免了大量的无用操作。

  • 数据结构简单,操作节省时间

    在 Redis 中,有以下五种常用的数据结构:

    • String:字符串类型,通常用作缓存、计数器和分布式锁等;
    • List:链表类型,用作队列、微博关注人时间轴列表等;
    • Hash:可以用于存储用户信息、hash表等;
    • Set:集合类型,用于去重、赞、踩、共同好友等;
    • Zset:有序集合,用于访问量排行榜、点击量排行榜等。

    此外,Redis对数据结构做了很多优化,诸如压缩表、对短数据进行压缩存储、跳表等,都加快了读取速度。

二、为什么Redis是单线程的

Redis是单线程的! 这一点是毋庸置疑的(好吧,Redis 6.0 网络读写部分是多线程的)。那为什么Redis使用单线程呢?而且还能有这么快的响应速度。

Redis is single threaded. How can I exploit multiple CPU / cores?

It’s not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound. For instance, using pipelining Redis running on an average Linux system can deliver even 1 million requests per second, so if your application mainly uses O(N) or O(log(N)) commands, it is hardly going to use too much CPU.

However, to maximize CPU usage you can start multiple instances of Redis in the same box and

### 跳表的查找过程与实现规则 跳表(Skip List)是一种基于有序链表的数据结构,通过添加多级索引提升查找效率。其查找过程类似于二分查找,但不依赖数组的随机访问特性,而是利用层级结构快速跳过大元素。 #### 查找过程 跳表的查找操作从最高层开始,逐步向下移动,最终在最底层找到目标值或确定其不存在。具体步骤如下: 1. 从当前节点的最高层开始遍历。 2. 如果当前层的下一个节点值小于目标值,则继续向右移动。 3. 如果当前层的下一个节点值大于目标值,则下降到下一层,并重复上述步骤。 4. 当到达最底层时,若下一个节点值等于目标值,则找到该节点;否则,目标值不存在于跳表中。 ```cpp struct SkipListNode { int _val; std::vector<SkipListNode*> _nextv; SkipListNode(int val, int height) : _val(val), _nextv(height, nullptr) {} }; // 查找函数示例 bool find(SkipListNode* head, int target) { SkipListNode* curr = head; for (int i = head->_nextv.size() - 1; i >= 0; i--) { while (curr->_nextv[i] && curr->_nextv[i]->_val < target) { curr = curr->_nextv[i]; } } curr = curr->_nextv[0]; // 移动到底层 return curr && curr->_val == target; } ``` #### 实现规则 - **层级结构**:每个节点可以有多级指针,表示不同层次的索引。层级数通常是随机生成的,以保证跳表的平衡性[^4]。 - **插入与删除**:插入和删除操作需要维护层级结构,确保跳表的高效性。插入时,根据随机数决定新节点的层级;删除时,需要更新所有相关层级的指针[^5]。 - **时间复杂度**:跳表的平均查找、插入和删除的时间复杂度为 $ O(\log n) $,最坏情况下为 $ O(n) $,但在实际应用中表现良好[^3]。 #### 效率分析 跳表的效率主要体现在减少查找路径长度上。假设每两个节点建立一个索引,查找时间复杂度可降低至 $ O(\log n) $。相比于平衡树(如红黑树、AVL树),跳表更易于实现,并且在并发环境下有更好的性能[^1]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值