告诉你Redis是多么牛

我不喜欢以前的标题,可是一篇介绍性的文章,读一读还不错。先转载一篇介绍的文章,有机会和你们一块儿讨论下redis内部的结构和实现原理。

概述:

Redis 是一个 Key-Value 存储系统。和 Memcached 相似,它支持存储的 value 类型相对更多,包括 string(字符串)、 list(链表)、 set(集合)和 zset(有序集合)。这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。在此基础上,Redis 支持各类不一样方式的排序。与 memcached 同样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了 master-slave(主从)同步。node

Key-Value存储系统

Key-Value Store 是当下比较流行的话题,尤为在构建诸如搜索引擎、IM、P2P、游戏服务器、SNS 等大型互联网应用以及提供云计算服务的时候,怎样保证系统在海量数据环境下的高性能、高可靠性、高扩展性、高可用性、低成本成为全部系统架构们挖苦心思考虑的重点,而
怎样解决数据库服务器的性能瓶颈是最大的挑战。
Key-Value Store 更加注重对海量数据存取的性能、分布式、扩展性支持上,并不须要传统关系数据库的一些特征,例如:Schema、事务、完整 SQL 查询支持等等,所以在分布式环境下的性能相对于传统的关系数据库有较大的提高。redis

为何要选择Key-Value Store

  1. 大规模互联网应用
    一类是仍然采用RDBMS,而后经过对数据库的垂直和水平切分将整个数据库部署到一个集群上,缺点在于它是针对特定应用,通用型不足
    另外一类就是google采用的方法,抛弃RDBMS,采用Key-Value形式存储,这样能够极大加强系统的可扩展性。数据库

  2. 云存储
    若是说上一个问题还有能够替代的解决方案(切割数据库)的话,那么对于云存储来讲,也许 key-value 的 store 就是惟一的解决方案了。云存储简单点说就是构建一个大型的存储平台给别人用,这也就意味着在这上面运行的应用实际上是不可控的。若是其中某个客户的应用随着用户的增加而不断增加时,云存储供应商是没有办法经过数据库的切割来达到 scale 的,由于这个数据是客户的,供应商不了解这个数据天然就无法做出切割。在这种状况下,key-value 的 store 就是惟一的选择了,由于这种条件下的 scalability 必须是自动完成的,不能有人工干预。这也是为何几乎全部的现有的云存储都是 key-value 形式的,例如 Amazon的 smipleDB,底层实现就是 key-value,还有 google 的  GoogleAppEngine,采用的是 BigTable的存储形式。缓存


Key-Value Store 最大的特色就是它的可扩展性,这也就是它最大的优点。所谓的可扩展性,
在我看来这里包括了两方面内容。一方面,是指 Key-Value Store 能够支持极大的数据的存储,它的分布式的架构决定了只要有更多的机器,就可以保证存储更多的数据。另外一方面,是指它能够支持数量不少的并发的查询。对于 RDBMS,通常几百个并发的查询就可让它很吃
力了,而一个 Key-Value Store,能够很轻松的支持上千的并发查询。下面而简单的罗列了一些特色:
  Key-value store:一个  key-value  数据存储系统,只支持一些基本操做,如: SET(key, value) 和  GET(key)  等;
  分布式:多台机器(nodes)同时存储数据和状态,彼此交换消息来保持数据一致,可视为一个完整的存储系统。
  数据一致:全部机器上的数据都是同步更新的、不用担忧获得不一致的结果;
  冗余:全部机器(nodes)保存相同的数据,整个系统的存储能力取决于单台机器(node)的能力;
  容错:若是有少数  nodes  出错,好比重启、当机、断网、网络丢包等各类  fault/fail  都不影响整个系统的运行;
  高可靠性:容错、冗余等保证了数据库系统的可靠性。服务器

初识Redis

Redis是一个开源的使用ANSI C语言编写,支持网络、可基于内存且可持久化的日志型、Key-Value数据库,而且提供多个语言的API,访问十分便捷。网络

Redis数据类型:

做为 Key-value 型数据库,Redis 也提供了键(Key)和键值(Value)的映射关系。可是,除
了常规的数值或字符串,Redis 的键值还能够是如下形式之一:
  Lists  (列表)
  Sets  (集合)
  Sorted sets  (有序集合)
  Hashes  (哈希表)
键值的数据类型决定了该键值支持的操做。Redis 支持诸如列表、集合或有序集合的交集、并集、查集等高级原子操做;同时,若是键值的类型是普通数字,Redis 则提供自增等原子操做。数据结构

Redis持久化:

一般,Redis 将数据存储于内存中,或被配置为使用虚拟内存。经过两种方式能够实现数据持久化:使用截图的方式,将内存中的数据不断写入磁盘;或使用相似 MySQL 的日志方式,记录每次更新的日志。前者性能较高,可是可能会引发必定程度的数据丢失;后者相反。架构

Redis主从同步:

Redis支持将数据同步到多台从库,这种特性对提升读取性能很是有益并发

Redis性能:

相比须要依赖磁盘记录每一个更新的数据库,基于内存的特性无疑给Redis带来了很是优秀的性能,读写操做之间有显著的性能差别
性能测试结果:分布式

SET操做每秒钟 110000 次,GET操做每秒钟 81000 次,服务器配置以下:
Linux 2.6, Xeon X3320 2.5Ghz.
stackoverflow 网站使用 Redis 作为缓存服务器。

适用场合:

Redis其实开创了一种新的数据存储思路,使用Redis,咱们不用再面对功能单调的数据库时,把精力放在如何把大象放进冰箱的问题,而是利用Redis提供的灵活多变的数据结构和数据操做,为不一样的大象构建不一样的冰箱。

下面是一些Redis经常使用的场景:

1. 取最新N个数据的操做

好比典型的取你网站的最新文章,经过下面方式,咱们能够将最新的 5000 条评论的 ID 放在Redis 的 List 集合中,并将超出集合部分从数据库获取。使用 LPUSH latest.comments<ID>命令,向 list 集合中插入数据插入完成后再用 LTRIM latest.comments 0 5000 命令使其永远只保存最近 5000 个 ID若是你还有不一样的筛选维度,好比某个分类的最新 N 条,那么你能够再建一个按此分类的List,只存 ID 的话,Redis 是很是高效的。

2. 排行榜应用,取TOP N操做

这个需求与上面需求的不一样之处在于,前面操做以时间为权重,这个是以某一个条件为权重,好比按购买的次数或者顶的次数,这时候就须要 sorted set 出马,将你要排序的值设置为sorted set的score,将具体的数据设置为相应的value,每次只须要执行一条ZADD命令便可。

3. 须要精确设定过时时间的应用

好比你能够把上面说到的 sorted  set 的 score 值设置成过时时间的时间戳,那么就能够简单地经过过时时间排序,定时清除过时数据了,不只是清除 Redis 中的过时数据,你彻底能够把 Redis 里这个过时时间当成是对数据库中数据的索引,用 Redis 来找出哪些数据须要过时删除,而后再精准地从数据库中删除相应的记录。

4.计数器应用
Redis的命令是原子性的,你能够轻松利用INCR、DECR命令来构建计数器系统(底层的写入是单线程模型,并发写会按到位顺序执行)

5.Uniq操做,获取某段时间全部数据去重值

这个使用Redis的Set数据结构最合适,只须要不断将数据往Set中扔就行,set就是集合,会自动去重

6.实时系统、发垃圾系统

经过上面说到的 set 功能,你能够知道一个终端用户是否进行了某个操做,能够找到其操做的集合并进行分析统计对比等。没有作不到,只有想不到。

7.Pub、Sub构建实时消息系统

Redis 的 Pub/Sub 系统能够构建实时的消息系统,好比不少用 Pub/Sub 构建的实时聊天系统的例子。

8. 构建队列系统

使用list能够构建队列系统,使用sorted set 甚至能够构建有优先级的队列系统。

9. 缓存

性能优于Memcached,而且更优秀的在于数据结构更加多样化

Redis做者的宣言

宣言中,做者列举了Redis的7大原则,能够向你们阐明Redis的思想,看了以后我以为Redis的做者的确牛叉,Redis这款产品这的是程序猿的福利:

  1. Redis 是一个操做数据结构的语言工具,它提供基于 TCP 的协议以操做丰富的数据结构。
    在 Redis 中,数据结构这个词的意义不只表示在某种数据结构上的操做,更包括告终构自己及这些操做的时间空间复杂度。

  2. Redis 定位于一个内存数据库,正是因为内存的快速访问特性,才使得 Redis 可以有如此高的性能,才使得 Redis 可以轻松处理大量复杂的数据结构,Redis 会尝试其它的存储方面的选择,可是永远不会改变它是一个内存数据库的角色。

  3. Redis 使用基础的 API 操做基础的数据结构, Redis 的 API 与数据结构同样,都是一些最基础的元素,你几乎能够将任何信息交互使用此 API 格式表示。做者调侃说,若是有其它非人类的智能生物存在,他们也能理解 Redis 的 API。由于它是如此的基础。(做者大大颇有趣)

  4. Redis 有着诗通常优美的代码,常常有一些不太了解 Redis  有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis  未实现的功能,但这对咱们来讲就像是非要给《红楼梦》接上后四十回同样。
    5.Redis 始终避免复杂化,咱们认为设计一个系统的本质,就是与复杂化做战。咱们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
    6.Redis 支持两个层成的 API,第一个层面包含部分操做 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操做。它们各有所长,可是咱们不会推出二者都支持的 API,但咱们但愿可以提供实例间数据迁移的命令,并执行 multi-key 操做。

  5. 咱们以优化代码为乐,咱们相信编码是一件辛苦的工做,惟一对得起这辛苦的就是去享受它。若是咱们在编码中失去了乐趣,那最好的解决办法就是停下来。咱们决不会选择让Redis很差玩的开发模式。


我只能感叹道:Redis乃神物,出污泥而不染,濯清涟而不妖

PS: Redis做者antirez曾笑称Redis为一个数据结构服务器,我认为这个仍是挺准确的,Redis的全部功能就是将数据以其固有的几种结构来保存,并提供给用户操做这几种结构的接口。

redis:官方传送门
redis中文:中文传送门


原文出处:https://www.jianshu.com/p/01b37cdb3f33  做者:Monkey_D_lufy