Redis与epoll

简介

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting), LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。--- From 官网

Memcached

  在memcached中value没有类型的概念,通过json表示复杂的数据结构。看似value的类型没有存在的意义,因为json可以表示很多复杂的数据类型,但是性能会差很多。类型不是很重要,重要的是redis的server中对每种类型都有自己的方法。比如,客户端要取出value中的某一个元素,memcached需要返回value所有的数据到client(网卡I/O,client端需要做转换),redis可以通过自己的方法就可以直接返回所需的元素。本质是解耦,在大数据中可以说,计算向数据移动。

秒级十万操作(1.5M ops/sec)

Redis原理

  • 单进程,单线程,单实例
  • 并发到来时,为什么效率很高?
    • 客户端可能带来一个或多个连接,连接先到达内核,redis进程和内核之间使用的是epoll系统调用(非阻塞的多路复用系统调用)。

I/O发展以及epoll

  • BIO
    • 早期处理到达内核的连接:通过线程/进程(Java是线程,Linux是进程)read系统调用读取连接的文件描述符。socket在这个时期是blocking(阻塞),所以读取socket产生的文件描述符时,如果数据没到的时候,read命令不能返回,也是阻塞的。此时面对很多连接只能抛出不同的线程/进程处理,所以CPU并没有时刻处理那些数据到达的线程,会产生资源浪费,同时,线程过多的话,切换线程也是有成本的。
  • NIO
    • 内核发生了变化,socket可以是非阻塞的(nonblock),也就是fd(文件描述符)可以使非阻塞的。
      • 可以在Linux中看到(一切皆文件),任何进程在Linux中都有自己I/O对应的文件描述符,查看进程文件描述符使用 cd /proc/进程号/fd)。
      • yuminstall man man-pages
      • man ls、man 2 read、man 2 socket
    1. 因为文件描述符是非阻塞,可以在一颗CPU上只使用一个线程去读取文件描述符,如果有数据就进行处理,如果没有数据,去轮询别的文件描述符(轮询发生在用户线程)。减少了线程切换带来的成本。
      • 此时是同步非阻塞(同步,所有东西都是我来处理,异步,交给别人处理。)
      • 问题:如果有大量的fd(1000个) ,代表用户进程轮询调用1000次内核,带来了很大的成本问题。
上一篇:洛谷P1563 [NOIP2016 提高组] 玩具谜题进阶解法


下一篇:设计模式六大原则之五:开闭原则