Redis 简介


如果文章对您有用,请关注点赞加收藏,博主会持续更新相关的专栏笔记🫡

Redis 是一个开源的高性能键值对数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,并借助许多高层级的接口使其可以胜任如缓存、队列系统等不同的角色。

接下来将分别介绍 Redis 的历史和特性,以使读者能够快速地对 Redis 有一个全面的了解。

历史与发展

2008 年,意大利的一家创业公司 Merzia 推出了一款基于 MySQL 的网站实时统计系统 LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo 便开始对 MySQL 的性能感到失望,于是他决定亲自为 LLOOGG 量身定做一个数据库,并于 2009 年开发完成,这个数据库就是 Redis。不过 Salvatore Sanfilippo 并不满足只将 Redis 用于 LLOOGG 这一款产品,而是希望让更多的人使用它,于是在同一年 Salvatore Sanfilippo 将 Redis 开源发布,并开始和 Redis 的另一名主要的代码贡献者 Pieter Noordhuis 一起继续着 Redis 的开发,直到今天。

Salvatore Sanfilippo 自己也没有想到,短短的几年时间,Redis 就拥有了庞大的用户群体。Hacker News 在 2012 年发布了一份数据库的使用情况调查,结果显示有近 12% 的公司在使用 Redis。国内如新浪微博、街旁和知乎,国外如 GitHub、Stack Overflow、Flickr、暴雪和 Instagram,都是 Redis 的用户。

VMware 公司从 2010 年开始赞助 Redis 的开发,Salvatore Sanfilippo 和 Pieter Noordhuis 也分别于同年的 3 月和 5 月加入 VMware,全职开发 Redis。

Redis 的代码托管在 GitHub 上,开发十分活跃【见下图】。截至交稿时,Redis 的最新版本是 2.6.9。

特性

作为一款个人开发的数据库,Redis 究竟有什么魅力吸引了如此多的用户呢?

存储结构

有过脚本语言编程经验的读者对字典【或称映射、关联数组】数据结构一定很熟悉,如代码 dict[“key”] = “value” 中 dict 是一个字典结构变量,字符串 “key” 是键名,而 “value” 是键值,在字典中我们可以获取或设置键名对应的键值,也可以删除一个键。

Redis 是 Remote Dictionary Server【远程字典服务器】的缩写,它以字典结构存储数据,并允许其他应用通过 TCP 协议读写字典中的内容。同大多数脚本语言中的字典一样,Redis 字典中的键值除了可以是字符串,还可以是其他数据类型。到目前为止 Redis 支持的键值数据类型如下:

  • 字符串类型
  • 散列类型
  • 列表类型
  • 集合类型
  • 有序集合类型

这种字典形式的存储结构与常见的 MySQL 等关系数据库的二维表形式的存储结构有很大的差异。举个例子,如下所示,我们在程序中使用 post 变量存储了一篇文章的数据【包括标题、正文、阅读量和标签】:

post["title"] = "Hello World!"
post["content"] = "Blablabla..."
post["views"] = 0
post["tags"] = ["PHP", "Ruby", "Node.js"]

现在我们希望将这篇文章的数据存储在数据库中,并且要求可以通过标签检索出文章。如果使用关系数据库存储,一般会将其中的标题、正文和阅读量存储在一个表中,而将标签存储在另一个表中,然后使用第三个表连接文章和标签表。需要查询时还得将三个表进行连接,不是很直观。而 Redis 字典结构的存储方式和对多种键值数据类型的支持使得开发者可以将程序中的数据直接映射到 Redis 中,数据在 Redis 中的存储形式和其在程序中的存储方式非常相近。使用 Redis 的另一个优势是其对不同的数据类型提供了非常方便的操作方式,如使用集合类型存储文章标签,Redis 可以对标签进行如交集、并集这样的集合运算操作。后面会专门介绍如何借助集合运算轻易地实现“找出所有同时属于 A 标签和 B 标签且不属于 C 标签”这样关系数据库实现起来性能不高且较为繁琐的操作。

内存存储与持久化

Redis 数据库中的所有数据都存储在内存中。由于内存的读写速度远快于硬盘,因此 Redis 在性能上对比其他基于硬盘存储的数据库有非常明显的优势,在一台普通的笔记本电脑上,Redis 可以在一秒内读写超过十万个键值。

将数据存储在内存中也有问题,例如,程序退出后内存中的数据会丢失。不过 Redis 提供了对持久化的支持,即将可以内存中的数据异步写入到硬盘中,同时不影响继续提供服务。

功能丰富

Redis 虽然是作为数据库开发的,但由于其提供了丰富的功能,越来越多的人将其用作缓存、队列系统等。Redis 可谓是名副其实的多面手。

Redis 可以为每个键设置生存时间【Time To Live,TTL】,生存时间到期后键会自动被删除。这一功能配合出色的性能让 Redis 可以作为缓存系统来使用,而且由于 Redis 支持持久化和丰富的数据类型,使其成为了另一个非常流行的缓存系统 Memcached 的有力竞争者。

讨论:关于 Redis 和 Memcached 优劣的讨论一直是一个热门的话题。在性能上 Redis 是单线程模型,而 Memcached 支持多线程,所以在多核服务器上后者的性能更高一些。然而,前面已经介绍过,Redis 的性能已经足够优异,在绝大部分场合下其性能都不会成为瓶颈。所以在使用时更应该关心的是二者在功能上的区别,如果需要用到高级的数据类型或是持久化等功能,Redis 将会是 Memcached 很好的替代品。

作为缓存系统,Redis 还可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定的规则自动淘汰不需要的键。

除此之外,Redis 的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易地实现一个高性能的优先级队列。同时在更高层面上,Redis 还支持“发布 / 订阅”的消息模式,可以基于此构建聊天室等系统。

简单稳定

即使功能再丰富,如果使用起来太复杂也很难吸引人。Redis 直观的存储结构使得通过程序与 Redis 交互十分简单。在 Redis 中使用命令来读写数据,命令语句之于 Redis 就相当于 SQL 语言之于关系数据库。例如在关系数据库中要获取 posts 表内 id 为 1 的记录的 title 字段的值可以使用如下 SQL 语句实现:

$ SELECT title FROM posts WHERE id = 1 LIMIT 1

相对应的,在 Redis 中要读取键名为 post:1 的散列类型键的 title 字段的值,可以使用如下命令语句实现:

$ hget post:1 title

其中 HGET 就是一个命令。Redis 提供了一百多个命令,听起来很多,但是常用的却只有十几个,并且每个命令都很容易记忆。后面就会发现 Redis 的命令比 SQL 语言要简单很多。

所有的命令见官网链接

Redis 提供了几十种不同编程语言的客户端库,这些库都很好地封装了 Redis 的命令,使得在程序中与 Redis 进行交互变得更容易。有些库还提供了可以将编程语言中的数据类型直接以相应的形式存储到 Redis 中【如将数组直接以列表类型存入 Redis】的简单方法,使用起来非常方便。

Redis 使用 C 语言开发,代码量只有 3 万多行。这降低了用户通过修改 Redis 源代码来使之更适合自己项目需要的门槛。对于希望“榨干”数据库性能的开发者而言,这无疑是一个很大的吸引力。

Redis 是开源的,所以事实上 Redis 的开发者并不止 Salvatore Sanfilippo 和 Pieter Noordhuis。截至目前,有将近 100 名开发者为 Redis 贡献了代码。良好的开发氛围和严谨的版本发布机制使得 Redis 的稳定版本非常可靠,如此多的公司在项目中使用了 Redis 也可以印证这一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱淋雨的鼬先生

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值