书海网短评:
适读人群:Redis的学习者或相关从业者等。Redis是当下极为流行的开源键值数据结构服务器。它提供了多种功能,可在此之上构建多种平台。本书定位为实用指南,旨在帮助读者深入理解Redis数据结构,以便充
Redis是当下极为流行的开源键值数据结构服务器。它提供了多种功能,可在此之上构建多种平台。
《深入理解Redis》定位为实用指南,旨在帮助读者深入理解Redis数据结构,以便充分发挥Redis的优秀功能。读者的Redis之旅始于对Redis需求的讨论,然后讲解了高级键管理方面的内容。接下来,读者将学习设计模式、在DevOps环境中使用Redis的*佳实践,以及Docker容器化范式。在这之后,读者将学习如何使用Redis集群和RedisSentinel进行扩展,随后将对Redis与其他NoSQL技术(如ElasticSearch和MongoDB)的结合进行说明。*后,读者将了解如何使用Redis为不相同的数据流构建实时数据分析仪表板。
◎探索Redis3.2中的新增功能
◎选择正确的Redis数据结构解决问题
◎理解Redis事件循环并实现自定义C命令
◎使用Redis服务器端脚本Lua解决复杂的工作流问题
◎配置Redis实例以达到*佳内存管理
◎使用Redis集群实现数据的分布式
◎使用RedisSentinel提升Redis解决方案的稳定性
◎将Redis用作现存的数据库和NoSQL环境的补充方案
◎充分利用Redis提供的各种功能,成为一位DevOps专家
让你的Redis技能产生质的飞跃,让开发酷炫应用从此轻而易举
《深入理解Redis》以由浅入深、由原理到应用场景的方式介绍了Redis这款NoSQL数据库产品。书中不仅细致地讲解了Redis中的数据结构及流行的使用模式,还针对Redis键的设计和管理,以及内存管理提出了建设性的方案。同时,作者深入Redis源码,将其内部构造通过源代码调试的方式进行呈现。《深入理解Redis》适合有一定NoSQL经验的开发者或者架构师阅读。读者可以从书中找到许多应用场景和解决方案,例如Docker部署、Redis消息队列、基于Redis的ETL应用和基于Redis的机器学习等。
汪佳南,拥有7年软件开发经验。对编程情有独钟,对产品设计很“感冒”,始终坚信技术可以改变世界。《RabbitMQ实战高效部署分布式消息队列》一书译者。
JeremyNelson是科罗拉多斯普林市的一所四年制私立文理学院科罗拉多学院的一位元数据和系统图书管理员。除了每周8小时的图书馆研究技术支持工作,为大学生提供信息素养指导,并监督图书馆的系统和编目部门这三项工作之外,Nelson正在积极研究和开发CatalogPull平台中的各种组件和开源工具,供科罗拉多大学、科罗拉多州研究图书馆联盟和国会图书馆使用。他还是语义网络初创公司KnowledgeLinks.io的联合创始人和CTO。
他之前在西部州科罗拉多大学和犹他大学有过图书馆工作经验。在成为图书管理员之前,他曾在各种软件公司和金融服务机构中担任程序员和项目经理。他的*一《深入理解Redis》BecomingaLeanLibrary于2015年出版,将精益创业和精益制造理念应用于图书馆和图书馆的运营。Nelson从诺克斯学院获得了本科学位,并从UniversityofIllinoisUrbana-Champaign获得了图书馆和信息科学的科学硕士。
关于审校者
EmilienKenler在从事了一些小型Web项目之后,在2008年高中时开始专注于游戏开发。直到2011年,他为不同的小组工作并专门从事系统管理。
2011年,在研究计算机科学工程的同时,他创立了一家公司销售Minecraft服务器。他基于像Node.js和RabbitMQ这样的新技术,创建了一个轻量级IaaS(https://github.com/HostYourCreeper/)。
此后,他在TaDaweb担任系统管理员,构建基础架构并创建管理部署和监控的工具。
2014年,他在东京Wizcorp开启了新的历程。同年,他毕业于UniversityofTechnologyofCompiègne。
Emilien为PacktPublishing编写了MariaDBEssentials。他还负责了LearningNagios4、MariaDBHighPerformance、OpenVZEssentials、VagrantVirtualDevelopmentEnvironmentCookbook和GettingStartedwithMariaDB-SecondEdition的审校。
SaurabhMinni拥有计算机科学专业的工程学位。他有超过10年的工作经验,通晓各种编程语言,包括汇编语言、C、C++、Java、Delphi、JavaScript、Android、iOS、PHP、Python、ZMQ、Redis、Mongo、KyotoTycoon、Cocoa、Carbon、ApacheKafka、ApacheStorm和ElasticSearch。总之,他是一位彻头彻尾的程序员,喜欢每天学习与技术相关的新事物。
目前,他在Near公司(这是一家神奇的初创公司,正在搭建位置智能平台)中担任技术架构师一职。除了处理几个项目之外,他还负责部署ApacheKafka集群。这有助于简化大数据处理系统中的数据消费。这些系统包括ApacheStorm、Hadoop,等等。
Saurabh同时也是ApacheKafkaCookbook一书的作者。这是一本有关ApacheKafka的书,由PacktPublishing出版。他还负责LearningApacheKafka一书的审校。该书由PacktPublishing出版。你可以在Twitter上通过@the100rabh联系他,也可以在https://github.com/the100rabh/上找到他。
目录
1为何选择Redis?1
合适之选?2
尝试使用Redis4
流行的使用模式9
Redis不合心意?马上再试试!11
总结13
2高级键管理与数据结构14
Redis键14
Redis键模式15
键分隔符和命名约定17
手动创建Redis模式19
解构Redis对象映射器22
键过期27
键的注意事项27
大O符号28
为自定义代码计算大O符号30
回顾Redis数据结构的时间复杂度32
字符串32
哈希33
列表34
集合35
有序集合36
高级有序集合操作39
位串和位操作39
HyperLogLogs41
总结42
3内存管理的建议与技巧44
配置Redis44
主从复制45
32位Redis45
INFOmemory详解47
键过期49
LRU键清除策略54
创建内存高效的Redis数据结构62
小巧的哈希、列表、集合和有序集合62
把位、字节和Redis字符串用作随机访问数组68
优化哈希,高效存储69
硬件和网络延迟72
操作系统建议74
总结75
4Redis编程第一部分:Redis核心、客户端和编程语言76
Redis的内部结构76
理解redis.h和redis.c83
Redis序列化协议93
RedisRDB格式97
使用Redis和Python创建协程99
使用Node.js和Redis实现Todo列表应用103
复制与公共访问106
总结106
5Redis编程第二部分:Lua脚本、管理与DevOps108
在Redis中使用Lua108
使用Redis的KEYS和ARGV117
Redis中的高级Lua脚本121
MARC21数据提取121
纸质文具在线商店123
让JSON-LD、Lua和Redis协同工作126
RedisLua调试器130
Redis的编程与管理133
主从复制134
使用MULTI和EXEC实现事务136
Redis在DevOps中扮演的角色139
总结140
6可伸缩性:Redis集群和Sentinel142
数据分区的方法142
范围分区143
列表分区145
哈希分区148
复合分区149
键哈希标签150
使用Twemproxy实现Redis集群151
使用关联数据片段服务器测试Twemproxy152
Redis集群的背景158
Redis集群概览159
使用Redis集群160
Redis集群实时重新配置及重新分片165
故障转移168
在Redis集群中替换或者升级节点170
使用RedisSentinel进行监控171
为区域代码列表分区配置RedisSentinel173
总结176
7Redis与互补的NoSQL技术177
NoSQL技术的繁荣177
Redis作为MongoDB的分析补充181
Redis作为ElasticSearch的预处理组件192
在BIBCAT中使用Redis和ElasticSearch193
ElasticSearch、Logstash和Redis198
Redis作为FedoraCommons的智能缓存补充199
总结205
8Docker容器与云端部署206
Linux容器206
与Redis相关的Docker基础211
Docker镜像中的层219
Docker文件系统后端220
Docker和Redis的问题227
使用DockerCompose打包应用程序227
Redis和AWS232
专门的云托管选项233
RedisLabs234
DigitalOceanRedis234
总结235
9任务管理与消息队列236
Redis的发布/订阅模式概述236
发布/订阅RESP回复237
SUBSCRIBE和UNSUBSCRIBERESP数组237
PSUBSCRIBE和UNSUBSCRIBE数组239
使用redis-cli进行发布/订阅240
Redis发布订阅实战242
第一个工作站采用Python进行发布订阅244
第二个工作站采用Node.js进行发布订阅246
第三个工作站使用Lua客户端进行发布订阅248
Redis键空间通知251
使用Redis和Celery进行任务管理255
GIS和RestMQ259
使用RestMQ进行任务管理262
使用Redis技术进行消息通信264
使用Disque进行消息通信264
总结266
10信息流的测量与管理267
基于Redis的ETL方案267
将JSON转换成RESP273
管理Redis时的安全考虑279
使用RedisWeb仪表板进行运营监测282
机器学习283
朴素贝叶斯与工作分类284
使用Redis实现线性规划294
总结299
来源300
译者序
对不少互联网企业来说,使用LNMP架构可以快速搭建起一套系统,产品可以迅速迭代并尽早投放市场。但随着访问量的上升,那些使用传统关系型数据库(例如MySQL)的网站开始显现出性能方面的问题。此外,越来越挑剔的用户也要求网站不能仅专注于功能特性,同时也要追求极致的产品体验(即高性能和高可用)。
一方面,架构师会在数据库层面做以下一系列优化。
1.配置主从
例如。为MySQL服务器配置主从。一台宕机,另一台可以顶上继续服务,以满足高可用的要求。
2.读写分离
配置一主多从。因为一般系统80%的请求都是读取操作,将这些操作分发到从服务器上可以有效地提升网站响应速度。
3.分库分表
随着数据量的增长,单库单表已经难以满足要求。一些诸如TDDL、Cobar、MyCAT等的MySQL分布式数据库中间件应运而生。
另一方面,架构师也会通过系统化的分析,以安插缓存层的方式缓解数据库的压力。对应用系统来说,缓存都应在设计之初就纳入考虑的范畴,成为系统不可或缺的一部分。我曾供职的一家公司就采用Redis作为缓存的实现方案。应用程序运行在两个同等的Tomcat容器里。Tomcat之前则配置了一台Nginx用于LoadBalance。由于用户Session存储在Redis中(通过Spring和Shiro的简单配置即可实现),应用的无状态性使得系统可以很方便地进行水平扩缩。另外,我们的业务要求用户每次浏览某个项目页面时进行访问计数(counting)。
为了避免频繁的数据库读写,我们将每个项目的浏览量的计算和读取交给了Redis。同时,为了避免意外导致的数据丢失,我们开启了Redis的持久化功能,并启动定时任务,每隔一段时间就将项目浏览次数同步到数据库中。
至于为何选择Redis而没有选择Memcached,当时考虑的主要原因是Redis支持更为丰富的数据模型。像上述页面访问量计数的需求,可以直接通过Redis的命令进行操作,而且利用Redis的单线程模型,应用程序无须编写同步代码。当然,缓存只是Redis的其中一个用途。一些典型的场景还包括排行榜、用户访问量统计、集合运算、消息队列等。国内外的一些大型互联网企业(例如京东、新浪、Pinterest等)都对Redis有不同程度的部署和应用。希望读者能够在《深入理解Redis》中找到自己想要的答案。
每次翻译都带给我不同的体验,并为我的工作和生活带来改变。在此,我要感谢电子工业出版社的编辑张春雨和负责审校的同事,是你们的细心指导保证了《深入理解Redis》的翻译质量。
同时,感谢我的父母和我的太太,在你们的陪伴和支持下,我得以专心工作。
由于时间仓促,文中难免有所疏漏,望不吝斧正。
汪佳南
前言
《深入理解Redis》旨在从两方面为读者构建Redis的基础知识。一方面,《深入理解Redis》提供了Redis及其技术背后的深层含义及理论;另一方面,拓展了Redis日常实用技能。《深入理解Redis》书名中的精通(Mastering)二字暗示了精通Redis是一个持续的过程,而非最终目的地。激动人心的是Redis持续开放地演进成为了时下强大的数据操作和存储技术。
Redis背后的设计哲学
在整个项目的生命周期中,SalvatoreSanfilippo对Redis的发展方向与功能发表了独到的观点和见解。在2015年1月的一篇有关Redis对比其他数据库的基准测试的博客中,
Sanfilippo声明“我不想说服开发者们采用Redis。我们只是尽力提供一款合适的产品。如果人们能够使用这款产品完成工作,我们会感到非常开心。这就是我的营销理念。”
Sanfilippo和他的Redis核心开发团队遵循着成功的开源管理模型:“仁慈独裁者”(BDL)
模型。该模型中只能有单独一个人作为最终独裁者,来裁决哪些能被提交到Redis代码库中。BDL模型的成功已经被诸如Linux内核开发和Python编程语言等项目证明过了。作为主要开发者和维护者的Sanfilippo成功地将BDL模型复制到了Redis中。
如果独裁者抛弃项目,或者更糟的是因病或者死亡而导致无法工作时,BDL模型的失效将是灾难性的。Redis浮现出来的另一个重大问题是当潜在的贡献者提交PullRequest时,针对这些提交的行动会被延迟,或者更多时候是被忽略。说句公道话,那些必须经过检查、测试并合并到主代码库上的变更的数量非常巨大,需要激情和专门的看门人。作为Linux内核项目的初创者及当前的BDL,LinusTorvalds已经看到自己的角色发生了转变,更多是在合并那些由其他开发者贡献的代码,同时相比亲自编写代码,他做的更多的是为Linux提供愿景和领导力。Sanfilippo在Redis主要的电子邮件通信上的一篇主题帖中确认了该问题,他给出了以下两大主要理由来继续Redis当前的BDL模型:
?项目开发与未来方向的一致性视角
?对任何新的或者出现的更改采取问责制
在Sanfilippo看来,Redis作为键值数据存储,其易于部署、内存占用少(就Redis本身来说,而不是指它的数据集!)、安全可靠等特性一直是Redis在开发者和组织中人气持续上升的关键因素。他的观点确实造成了紧张的关系,特别是当提出Redis的新功能,例如使哈希中具体子值(sub-values)过期,或者为可选功能提供可加载模块时,这些特性都被拒之门外。Sanfilippo对于保持Redis的小巧并专注于使其成为内存数据库的渴望,推动发展,在2011年的博客中,他用有关Redis和Redis开发过程的七条宣言阐明了他的观点,简述如下。
1.用于抽象数据类型的DSL。Redis是一门领域特定语言(DSL),用于抽象数据结构的表达和使用。这些数据结构不仅包括了操作(Redis命令),还包括了使用Redis相关命令存储和操作这些数据结构的内存效率和时间复杂度。
2.内存存储是第一要务。通过将所有数据存储在计算机内存中,跨系统的Redis的性能更为一致,用于实现这些数据结构的众多算法以更为可预测的方式运行,同时诸如有序集合这样的更为复杂的数据类型在内存数据库中更容易实现。
3.基础数据结构对应基础API。Redis为基础数据结构实现了一套基础API。这套API由Redis命令和对应的数据结构组成。它尝试清晰地反映API从计算机内存中读取和写入的数据结构。Redis遵循这一设计理念,通过更简单的数据结构操作来组合实现更为复杂的操作。
4.代码如诗。这是所有七条宣言之中最难以渗透的。Sanfilippo将他的审美偏好融入到代码之中以契合Redis这一长篇巨著。他认为Redis的编码风格和方法能够帮助人们书写一段叙述。因此,是否包含第三方代码部分取决于它能否很好地契合Redis的叙述和Redis的源代码。
5.我们反对复杂。避免代码复杂性。如果要在使用大量代码来实现小型功能与舍弃该功能之间做出选择的话,那么Redis会选择后者,以舍弃额外的复杂性和向代码库中添加复杂性所带来的开销。
6.两层API。一套是API的子集,以分布式的方式运行;另一套更大型、功能更为丰富,用来支持多键操作。这种分离设计支持像Redis主从和Redis集群操作模式这样重要的功能。
7.我们以优化为乐。通常对于开发者和技术运营者来说,这是一种情感诉求,也是一段非常聪明的声明。调优技术来解决疑难杂症所带来的刺激能够激起快乐的感觉及对Redis未来无限可能的兴奋。
《深入理解Redis》涵盖内容
阅读《深入理解Redis》时你会发现其贯穿着两大主题,以平行的方式展示了流行时尚的运营和过程的开发/运营二元论,即众所周知的DevOps。为了有助于读者更有针对性地学习章节中包含的内容,每个章节的主题会被归类为软件开发或者系统运营。由于两者之间的边界越来越模糊,对每个趋势中主题的深刻理解能够增强你和你团队的能力,以便快速高效地为项目开发和部署Redis解决方案,或者将Redis作为技术基础设施需求的一部分。
第1章介绍了由Redis之父和主要维护者SalvatoreSanfilippo所阐明的Redis开发哲学。
第2章通过详细阐述和解释Redis数据结构和键管理为读者构建起Redis的基础知识,其中包括了如何为应用程序构造既有意义又有表达力的键模式这一重要主题。
第3章讲解了Redis提供的用来优化应用程序内存使用的各种选项,其中包括了Redis支持的基于最近较少使用(LRU)的各种缓存和Redis中的键驱逐(evict)策略。
第4章是有关应用程序编程的高级主题。本章从概述Redis核心的C语言实现开始,通过对精心挑选的C代码片段进行深入地讲解来加深你对Redis的理解。然后讲到了如何使用三种不同的Redis客户端,并展示了分别使用Python、Node.js和Haskell的编程示例。第5章是有关应用程序编程的高级主题。本章从概述Redis服务器端Lua脚本及如何在Redis中更高效地使用Lua开始讲起。之后,拓展讲解了一些流行的Redis编程设计模式,列举了几个具体实例,描述了不同的个体和公司在运营操作中是如何使用这些模式的。本章最后从软件开发者的角度描述了Redis是如何应用于典型的DevOps场景中。
第6章探索了两个最近添加到Redis中的Redis集群和RedisSentinel。RedisSentinel是一种特殊的高可用模式,用来监控主从服务器的健康状况,并能够在任意Redis主从实例故障时进行切换。之前提到的Redis集群现在可用于产品环境中了。对于那些太大而不能存入单台机器的大型数据来说,Redis集群能够通过运行多个实例并将键进行分片的方式来完成存储。虽然这些主题更关注运营方面,但是在采用Redis的工程解决方案时至少应该知









