Redis 的诞生
Redis 的创建者
Salvatore Sanfilippo (antirez),男,意大利人,出生并居住在西西里 岛,个人网站 http://invece.org/ 。早年为系统管理员,关注计算机安全领域,于 1999 年发明了 idle scan 扫描技术,该技术现在在 nmap 扫描器上也有实现。2004 年~2006 年期间在做嵌入式方面的工作,并 为此写了名为 Jim 的Tcl 解释器 、《Tcl Wise:Guide to the Tcl programming language》一书以及《Tcl the Misunderstood》文档。(Redis 的事件处理器就重写自 Jim 的事件循环,而 Redis 的测试套件也使用 Tcl 语言来写的)。除此之外,他在2006 还写了 Hping —— 一个 TCP/IP 包分析器。之后开始接触 web ,在 2007 年和另一个朋友共同创建了 LLOOGG.com,并因为解决这个网站的负载问题而在 2009 年 2 月 26 日发明了 Redis
LLOOGG.com
一个访客信息追踪网站,网站可以通过 JavaScript 脚本,将访客的 IP 地址、所属国家、阅览器信息、被访问页面的地址等数据传送给 LLOOGG.com 。然后 LLOOGG.com 会将这些浏览数据通过 web 页面实时地展示给用户, 并储存起最新的 5 至 10,000 条浏览记录以便进行查阅。
LLOOGG.com 用户界面
LLOOGG.com 的运作方式
为了记录每个被追踪网站的浏览信息, LLOOGG.com 需要为每个被追踪的网站创建一个列表(list),每个列表需要根据用 户的设置,储存最新的 5 至 10,000 条浏览记录。
每当某个被追踪的网站新增一条 浏览记录时, LLOOGG.com 就会将这条新的浏览记录推入(push)到与该网站相对应的列表里面,当列表的 长度超过用户指定的最大长度时,程序每向列表推入一条新的记录,就需要从列表中弹出(pop)一条最旧的记录。
LLOOGG.com 的负载问题
随着 LLOOGG.com 的用户越来越多, LLOOGG.com 要维护的列表数量也越来越多,要执行的推入和弹出操作也越来越多。LLOOGG.com 当时使用 MySQL 数据库,而 MySQL 每次执行推入和弹出操作都要进行硬盘写入和读取,程序的性能严重受制于硬盘 I/O 。 最终,LLOOGG.com 所使用的 MySQL 再也没办法在当时的 VPS上处理新增的大量负载,因为 LLOOGG.com 当时还没有找到盈利模式,所以 为了尽量节约开支, antirez 没有选择直接升级 LLOOGG.com 所使用的 VPS ,而是打算另寻 办法,在现有硬件的基础上,通过提升列表操作的性能来解决 负载问题。
Redis 的诞生
为了在不升级 VPS 的前提下,解决 LLOOGG.com 的负载问题,antirez 决定自己写一个具有列表 结构的内存数据库原型(prototype)。
这个数据库原型支持 O(1) 复杂的推入和弹出操作,并且将数据储存在内存而不是硬盘,所以程序的性能不会受到硬盘 I/O 限制,可以以极快的速度 执行针对列表的推入和弹出操作。经过实验,这个原型的确可以在不升 级 VPS 的前提下,解决 LLOOGG.com 当时的负载问题。
于是 antirez 使用 C 语言重写了这个内存数据库,并给它加上了持久化功能, Redis 就此诞生!
Redis 的演进
Redis 的特色
独特的键值对模型
很多数据库只能处理一种数据结构:
• SQL 数据库 —— 表格
• Memcached —— 键值对数据库,键和值都是字符串
• 文档数据库(CouchDB、MongoDB) —— 由 JSON/BSON 组成的文档(document)
而一旦数据库提供的数据结构不适合去做某件事的话,程序写起来就会非常地麻烦和不自然。
Redis 也是键值对数据库,但和 Memcached 不同的是,Redis 的值不仅可以是字符串,它还可以其他五种数据结构中的任意一种。通过选用不同的数据结构,用户可以使用 Redis 解决各式各样的问题。
内存储存,速度极快
Redis 将数据储存在内存里面,读写数据的时候都不会受到硬盘 I/O 速度的限制,所以速度极快。
丰富的附加功能
持久化功能:将储存在内存里面的数据保存到硬盘里面,保障数据安全,方便进行数据备份和恢复。
发布与订阅功能:将消息同时分发给多个客户端,用于构建广播系统。 过期键功能:为键设置一个过期时间,让它在指定的时间之后自动被删除。
事务功能:原子地执行多个操作,并提供乐观锁功能,保证处理数据时的安全性。
脚本功能:在服务器端原子地执行多个操作,完成复杂的功能,并减少客户端与服务器之间的通信往返次数。
复制:为指定的 Redis 服务器创建一个或多个复制品,用于提升数据安全性,并分担读请求的负载。
Sentinel:监控 Redis 服务器的状态,并在服务器发生故障时,进行自动故障转移。
集群:创建分布式数据库,每个服务器分别执行一部分写操作和读操作。
完善的文档
Redis 具有完善、易读的文档,加上 Redis 本身功能的简单性,就算是新手也可以 轻松上手。
良好的支持
antirez 非常勤奋,在每个版本都会不断地增加有用的新功能:
• 2.6 新增脚本功能,并为很多命令添加了多参数支持(比如 SADD、ZADD、等等);
• 2.8 添加了数据库通知功能,HyperLogLog 数据结构以及 SCAN 命令,实现了部分重同步;
• 3.0 将推出稳定版的 Redis 集群,另外还有更多新功能陆续开发中……
Bug 一旦出现就会很快被修复,齐全的测试套件以及稳扎稳打的开发策略,使得 Redis 非常健壮可靠。有问题时,在 Redis 的论坛上发贴,或者到 Redis 的 GitHub 页面发 issue ,又或者直接和作者 antirez联系,通常都可以很快得到回应。Pivotal 公司雇用 antirez 全力开发Redis,无后顾之忧;这间公司也提供专门的 Redis 开发和维护咨询服务。阿里云、百度云、Amazon、 RedisLab 等公司都提供了基于Redis 的应用服务。
广泛的使用
Twitter 使用 Redis 来储存用户时间线(user timeline)。
StackOverflow 使用 Redis 来进行缓存和消息分发。
Pinterest 使用 Redis 来构建关注模型(follow model)和兴趣图谱(interest graph)。
Flickr 使用 Redis 来构建队列。
Github 使用 Redis 作为持久化的键值对数据库,并使用 Resque 来实现消息队列。
新浪微博使用 Redis 来实现计数器、反向索引、排行榜、消息 队列,并储存用户关系。
知乎使用 Redis 来进行计数、缓存、消息分发和任务调度。 在课程的后续内容中,我们也会使用 Redis 来实现这里提到的一些功能。