Redis开发与运维(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-09 23:32:35

点击下载

作者:付磊,张益军

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Redis开发与运维

Redis开发与运维试读:

前言

Redis作为基于键值对的NoSQL数据库,具有高性能、丰富的数据结构、持久化、高可用、分布式等特性,同时Redis本身非常稳定,已经得到业界的广泛认可和使用。掌握Redis已经逐步成为开发和运维人员的必备技能之一。

本书关注了Redis开发运维的方方面面,尤其对于开发运维中如何提高效率、减少可能遇到的问题进行详细分析,但本书不单单介绍怎么解决这些问题,而是通过对Redis重要原理的解析,帮助开发运维人员学会找到问题的方法,以及理解背后的原理,从而让开发运维人员不仅知其然,而且知其所以然。

本书涵盖内容

第1章 初识Redis,带领读者进入Redis的世界,了解它的前世今生、众多特性、应用场景、安装配置、简单使用,最后对Redis发展过程中的重要版本进行说明,可以让读者对Redis有一个全面的认识。

第2章 API的理解和使用,全面介绍了Redis提供的5种数据结构字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)的数据模型、常用命令、典型应用场景,并且每个小节都会给出在Redis开发过程可能要注意的坑和技巧。同时本章还会对Redis的单线程处理机制、键值管理做一个全面介绍,通过对这些原理的理解,读者可以在合适的应用场景选择合适的数据结构和命令进行开发,有效提高程序效率,降低可能产生的问题和隐患。

第3章 小功能大用处,除了5种数据结构外,Redis还提供了诸如慢查询、Redis Shell、Pipeline、Lua脚本、Bitmaps、HyperLogLog、发布订阅、GEO等附加功能,在这些功能的帮助下,Redis的应用场景更加丰富。

第4章 客户端,本章重点关注Redis客户端的开发,介绍了Redis的客户端通信协议、详细讲解了Java客户端Jedis的使用技巧,同时通过从原理角度剖析在开发运维中,客户端的监控和管理技巧,最后给出客户端开发中常见问题以及案例讲解。

第5章 持久化,Redis的持久化功能有效避免因进程退出造成的数据丢失问题,本章首先介绍RDB和AOF两种持久化配置和运行流程,其次对常见的持久化问题进行定位和优化,最后结合Redis常见的单机多实例部署场景进行优化。

第6章 复制,在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,用于故障恢复和负载均衡等需求,Redis也是如此。它为我们提供了复制(replication)功能,实现了多个相同数据的Redis副本。复制功能是高可用Redis的基础,后面章节的哨兵和集群都是在复制的基础上实现高可用。

第7章 Redis的噩梦:阻塞,Redis是典型的单线程架构,所有的读写操作都在一条主线程中完成的。当Redis用于高并发场景时这条线程就变成了它的生命线。如果出现阻塞哪怕是很短时间对于我们的应用来说都是噩梦。导致阻塞问题的场景大致分为内在原因和外在原因,本章将进行详细分析。

第8章 理解内存,Redis所有的数据存在于内存中,如何高效利用Redis内存变得非常重要。高效利用Redis内存首先需要理解Redis内存消耗在哪里,如何管理内存,最后再深入到如何优化内存。掌握这些知识后相信读者能够实现用更少的内存存储更多的数据从而降低成本。

第9章 哨兵,Redis从2.8版本开始正式提供了Redis Sentinel,它有效解决了主从复制模式下故障转移的若干问题,为Redis提供了高可用功能。本章将一步步解析Redis Sentinel的相关概念、安装部署、配置、命令使用、原理解析,最后分析了Redis Sentinel运维中的一些问题。

第10章 集群,是本书的重头戏,Redis Cluster是Redis3提供的Redis分布式解决方案,有效解决了Redis分布式方面的需求,理解应用好Redis Cluster将极大的解放我们对分布式Redis的需求,同时它也是学习分布式存储的绝佳案例。本章将针对RedisCluster的数据分布,搭建集群,节点通信,请求路由,集群伸缩,故障转移等方面进行分析说明。

第11章 缓存设计,缓存能够有效加速应用的读写速度,以及降低后端负载,对于开发人员进行日常应用的开发至关重要,但是将缓存加入应用架构后也会带来一些问题,本章将介绍缓存使用和设计中遇到的问题,具体包括:缓存的收益和成本、缓存更新策略、缓存粒度控制、穿透问题优化、无底洞问题优化、雪崩问题优化、热点key优化。

第12章 开发运维的“陷阱”,介绍Redis开发运维中的一些棘手问题,具体包括:Linux配置优化、flush误操作数据恢复、如何让Redis变得安全、bigkey问题、热点key问题。

第13章 Redis监控运维云平台CacheCloud,介绍笔者所在团队开源的Redis运维工具CacheCloud,它有效解决了Redis监控和运维中的一些问题,本章将按照快速部署、机器部署、接入应用、用户功能、运维功能多个维度全面的介绍CacheCloud,相信在它的帮助下,读者可以更好的监控和运维好Redis。

第14章 Redis配置统计字典,会对Redis的系统状态信息以及全部配置做一个全面的梳理,希望本章能够成为Redis配置统计字典,协助大家分析和解决日常开发和运维中遇到的问题。

目标读者

本书深入浅出地介绍了Redis相关知识,因此可以作为Redis新手的入门教程,同时本书凝聚了两位笔者在Redis开发运维的多年经验,对于需要进一步提高Redis开发运维能力的读者也非常适合。读者可以参考下图,结合自身对于开发运维的需求进行阅读,但笔者依然建议读者对每一章都进行阅读。

读者反馈和勘误

由于笔者能力有限,书中难免会存在错误和疏漏,读者有任何意见和建议可以通过发送邮件、网站留言,或者直接在QQ群留言,我们会在第一时间进行反馈。

邮箱:redis_devops_book@163.com

网站:https://cachecloud.github.io/,该网站持续更新Redis开发运维的相关知识和经验。

QQ群:534429768著者2016年9月致谢

感谢业内众多Redis专家对于本书的审阅,他们分别是黄健宏、杨卫华(Tim Yang)、刘奇、卓汝林、黄鹏程、张海雷、诸超、陈宗志、李成武,他们为本书提出很宝贵的意见和建议。

感谢我们公司的领导和同事,没有他们的帮助和支持,本书无法按时完成,他们是马义、田文宝、闵博、陈实、张啸丰、赵欣莅、张文、董刚锋、赵路、高永飞、曾旭、孙孟萌、田文龙、庞云龙、李明月、戴育东、单颖博、唐虎、贺永明、郭岭、谷海波。

我们要感谢机械工业出版社的吴怡编辑对我们写作的支持、鼓励和指导,她一丝不苟的工作态度让人钦佩。

最后,我们要感谢家人和朋友,感谢在写书期间他们的支持和鼓励,从而让本书顺利完成。第1章初识Redis

本章将带领读者进入Redis的世界,了解它的前世今生、众多特性、典型应用场景、安装配置、如何好用等,最后会对Redis发展过程中的重要版本进行说明,本章主要内容如下:

·盛赞Redis

·Redis特性

·Redis使用场景

·用好Redis的建议

·正确安装启动Redis

·Redis重大版本1.1 盛赞Redis[1]

Redis是一种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis中的值可以是由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此Redis可以满足很多的应用场景,而且因为Redis会将所有数据都存放在内存中,所以它的读写性能非常惊人。不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。总之,如果在合适的场景使用好Redis,它就会像一把瑞士军刀一样所向披靡。[2]

2008年,Redis的作者Salvatore Sanfilippo在开发一个叫LLOOGG的网站时,需要实现一个高性能的队列功能,最开始是使用MySQL来实现的,但后来发现无论怎么优化SQL语句都不能使网站的性能提高上去,再加上自己囊中羞涩,于是他决定自己做一个专属于LLOOGG的数据库,这个就是Redis的前身。后来,Salvatore [3]Sanfilippo将Redis1.0的源码开放到GitHub上,可能连他自己都没想到,Redis后来如此受欢迎。

假如现在有人问Redis的作者都有谁在使用Redis,我想他可以开句玩笑的回答:还有谁不使用Redis,当然这只是开玩笑,但是从Redis的官方公司统计来看,有很多重量级的公司都在使用Redis,如国外的Twitter、Instagram、Stack Overflow、GitHub等,国内就更多了,如果单单从体量来统计,新浪微博可以说是全球最大的Redis使用者,除了新浪微博,还有像阿里巴巴、腾讯、百度、搜狐、优酷土豆、美团、小米、唯品会等公司都是Redis的使用者。除此之外,许多开源技术像ELK等已经把Redis作为它们组件中的重要一环,而且Redis会在未来的版本中提供模块系统让第三方人员实现功能扩展,让Redis发挥出更大的威力。所以,可以这么说,熟练使用和运维Redis已经成为开发运维人员的一个必备技能。

[1] http://redis.io

[2] http://antirez.com

[3] https://github.com/antirez/redis1.2 Redis特性

Redis之所以受到如此多公司的青睐,必然有之过人之处,下面是关于Redis的8个重要特性。

1.速度快

正常情况下,Redis执行命令的速度非常快,官方给出的数字是读写性能可以达到10万/秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了Redis除此之快的速度,可以大致归纳为以下四点:

·Redis的所有数据都是存放在内存中的,表1-1是谷歌公司2009年给出的各层级硬件执行速度,所以把数据放在内存中是Redis速度快的最主要原因。

·Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快。

·Redis使用了单线程架构,预防了多线程可能产生的竞争问题。

·作者对于Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。表1-1 谷歌公司给出的各层级硬件执行速度

2.基于键值对的数据结构服务器

几乎所有的编程语言都提供了类似字典的功能,例如Java里的map、Python里的dict,类似于这种组织数据的方式叫作基于键值的方式,与很多键值对数据库不同的是,Redis中的值不仅可以是字符串,而且还可以是具体的数据结构,这样不仅能便于在许多应用场景的开发,同时也能够提高开发效率。Redis的全称是REmote Dictionary Server,它主要提供了5种数据结构:字符串、哈希、列表、集合、有序集合,同时在字符串的基础之上演变出了位图(Bitmaps)和HyperLogLog两种神奇的“数据结构”,并且随着LBS(Location Based Service,基于位置服务)的不断发展,Redis3.2版本中加入有关GEO(地理信息定位)的功能,总之在这些数据结构的帮助下,开发者可以开发出各种“有意思”的应用。

3.丰富的功能

除了5种数据结构,Redis还提供了许多额外的功能:

·提供了键过期功能,可以用来实现缓存。

·提供了发布订阅功能,可以用来实现消息系统。

·支持Lua脚本功能,可以利用Lua创造出新的Redis命令。

·提供了简单的事务功能,能在一定程度上保证事务特性。

·提供了流水线(Pipeline)功能,这样客户端能将一批命令一次性传到Redis,减少了网络的开销。

4.简单稳定

Redis的简单主要表现在三个方面。首先,Redis的源码很少,早期版本的代码只有2万行左右,3.0版本以后由于添加了集群特性,代码增至5万行左右,相对于很多NoSQL数据库来说代码量相对要少很多,也就意味着普通的开发和运维人员完全可以“吃透”它。其次,Redis使用单线程模型,这样不仅使得Redis服务端处理模型变得简单,而且也使得客户端开发变得简单。最后,Redis不需要依赖于操作系统中的类库(例如Memcache需要依赖libevent这样的系统类库),Redis自己实现了事件处理的相关功能。

Redis虽然很简单,但是不代表它不稳定。以笔者维护的上千个Redis为例,没有出现过因为Redis自身bug而宕掉的情况。

5.客户端语言多

Redis提供了简单的TCP通信协议,很多编程语言可以很方便地接入到Redis,并且由于Redis受到社区和各大公司的广泛认可,所以支持Redis的客户端语言也非常多,几乎涵盖了主流的编程语言,例[1]如Java、PHP、Python、C、C++、Nodejs等,第4章我们将对Redis的客户端进行详细说明。

6.持久化

通常看,将数据放在内存中是不安全的,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此Redis提供了两种持久化方式:RDB和AOF,即可以用两种策略将内存的数据保存到硬盘中(如图1-1所示),这样就保证了数据的可持久性,第5章我们将对Redis的持久化进行详细说明。图1-1 Redis内存到磁盘的持久化

7.主从复制

Redis提供了复制功能,实现了多个相同数据的Redis副本(如图1-2所示),复制功能是分布式Redis的基础。第6章我们将对Redis的复制进行详细说明。图1-2 Redis主从复制架构

8.高可用和分布式

Redis从2.8版本正式提供了高可用实现Redis Sentinel,它能够保证Redis节点的故障发现和故障自动转移。Redis从3.0版本正式提供了分布式实现Redis Cluster,它是Redis真正的分布式实现,提供了高可用、读写和容量的扩展性。

[1] http://redis.io/clients1.3 Redis使用场景

上节我们已经了解了Redis的若干个特性,本节来看一下Redis的典型应用场景有哪些?1.3.1 Redis可以做什么

1.缓存

缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。Redis提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。第11章将对缓存的设计与使用进行详细说明。

2.排行榜系统

排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

3.计数器应用

计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

4.社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。

5.消息队列系统

消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。1.3.2 Redis不可以做什么

实际上和任何一门技术一样,每个技术都有自己的应用场景和边界,也就是说Redis并不是万金油,有很多适合它解决的问题,但是也有很多不合适它解决的问题。我们可以站在数据规模和数据冷热的角度来进行分析。

站在数据规模的角度看,数据可以分为大规模数据和小规模数据,我们知道Redis的数据是存放在内存中的,虽然现在内存已经足够便宜,但是如果数据量非常大,例如每天有几亿的用户行为数据,使用Redis来存储的话,基本上是个无底洞,经济成本相当的高。

站在数据冷热的角度看,数据分为热数据和冷数据,热数据通常是指需要频繁操作的数据,反之为冷数据,例如对于视频网站来说,视频基本信息基本上在各个业务线都是经常要操作的数据,而用户的观看记录不一定是经常需要访问的数据,这里暂且不讨论两者数据规模的差异,单纯站在数据冷热的角度上看,视频信息属于热数据,用户观看记录属于冷数据。如果将这些冷数据放在Redis中,基本上是对于内存的一种浪费,但是对于一些热数据可以放在Redis中加速读写,也可以减轻后端存储的负载,可以说是事半功倍。

所以,Redis并不是万金油,相信随着我们对Redis的逐步学习,能够清楚Redis真正的使用场景。1.4 用好Redis的建议

1.切勿当作黑盒使用,开发与运维同样重要

很多使用Redis的开发者认为只要会用API开发相应的功能就可以,更有甚者认为Redis就是get、set、del,不需要知道Redis的原理。但是在我们实际运维和使用Redis的过程中发现,很多线上的故障和问题都是由于完全把Redis当做黑盒造成的,如果不了解Redis的单线程模型,有些开发者会在有上千万个键的Redis上执行keys*操作,如果不了解持久化的相关原理,会在一个写操作量很大的Redis上配置自动保存RDB。而且在很多公司内只有专职的关系型数据库DBA,并没有NoSQL的相关运维人员,也就是说开发者很有可能会自己运维Redis,对于Redis的开发者来说既是好事又是坏事。站在好的方面看,开发人员可以通过运维Redis真正了解Redis的一些原理,不单纯停留在开发上。站在坏的方面看,Redis的开发人员不仅要支持开发,还要承担运维的责任,而且由于运维经验不足可能会造成线上故障。但是从实际经验来看,运维足够规模的Redis会对用好Redis更加有帮助。

2.阅读源码

我们在前面提到过,Redis是开源项目,由于作者对Redis代码的极致追求,Redis的代码量相对于许多NoSQL数据库来说是非常小的,也就意味着作为普通的开发和运维人员也是可以“吃透”Redis的。通过阅读优秀的源码,不仅能够加深我们对于Redis的理解,而且还能提高自身的编码水平,甚至可以对Redis做定制化,也就是说可以修改Redis的源码来满足自身的需求,例如新浪微博在Redis的早期版本上做了很多的定制化来满足自身的需求,豌豆荚也开源基于Proxy的Redis分布式实现Codis。1.5 正确安装并启动Redis

通常来说,学习一门技术最好的方法就是实战,所以在学习Redis这样一个实战中产生的技术时,首先把它安装部署起来,值得庆幸的是,相比于很多软件和工具部署步骤繁杂,Redis的安装不得不说是非常简单,本节我们将学习如何安装Redis。注意

在写本书时,Redis4.0已经发布RC版,但是大部分公司还都在使用3.0或更早的版本(2.6或2.8),本书所讲的内容基于Redis3.0。1.5.1 安装Redis

1.在Linux上安装Redis

Redis能够兼容绝大部分的POSIX系统,例如Linux、OS X、OpenBSD、NetBSD和FreeBSD,其中比较典型的是Linux操作系统(例如CentOS、Redhat、Ubuntu、Debian、OS X等)。在Linux安装软件通常有两种方法,第一种是通过各个操作系统的软件管理软件进行安装,例如CentOS有yum管理工具,Ubuntu有apt。但是由于Redis的更新速度相对较快,而这些管理工具不一定能更新到最新的版本,同时前面提到Redis的安装本身不是很复杂,所以一般推荐使用第二种方式:源码的方式进行安装,整个安装只需以下六步即可完成,以3.0.7版本为例:$ wget http://download.redis.io/releases/redis-3.0.7.tar.gz$ tar xzf redis-3.0.7.tar.gz$ ln -s redis-3.0.7 redis$ cd redis$ make$ make install

1)下载Redis指定版本的源码压缩包到当前目录。

2)解压缩Redis源码压缩包。

3)建立一个redis目录的软连接,指向redis-3.0.7。

4)进入redis目录。

5)编译(编译之前确保操作系统已经安装gcc)。

6)安装。

这里有两点要注意:第一,第3步中建立了一个redis目录的软链接,这样做是为了不把redis目录固定在指定版本上,有利于Redis未来版本升级,算是安装软件的一种好习惯。第二,第6步中的安装是将Redis的相关运行文件放到/usr/local/bin/下,这样就可以在任意目录下执行Redis的命令。例如安装后,可以在任何目录执行redis-cli–v查看Redis的版本。$ redis-cli -v redis-cli 3.0.7注意

第12章将介绍更多Linux配置优化技巧,为Redis的良好运行保驾护航。

2.在Windows上安装Redis

Redis的官方并不支持微软的Windows操作系统,但是Redis作为一款优秀的开源技术吸引到了微软公司的注意,微软公司的开源技术组在GitHub上维护一个Redis的分支:https://github.com/MSOpenTech/redis。

那为什么Redis的作者没有开发和维护针对Windows用户的Redis版本呢?这里可以简单分析一下:首先Redis的许多特性都是和操作系统相关的,Windows操作系统和Linux操作系统有很大的不同,所以会增加维护成本,而且更重要的是大部分公司都在使用Linux操作系统,而Redis在Linux操作系统上的表现已经得到了实践的验证。对于使用Windows操作系统的读者,可以通过安装虚拟机来体验Redis的诸多特性。注意

对Windows版本的Redis感兴趣的读者,可以尝试安装和部署Windows版本的Redis,但是本书中的知识和例子不能确保在Windows下能够运行。1.5.2 配置、启动、操作、关闭Redis

Redis安装之后,src和/usr/local/bin目录下多了几个以redis开头可执行文件,我们称之为Redis Shell,这些可执行文件可以做很多事情,例如可以启动和停止Redis、可以检测和修复Redis的持久化文件,还可以检测Redis的性能。表1-2中分别列出这些可执行文件的说明。表1-2 Redis可执行文件说明

Redis持久化和Redis Sentinel分别在第5章和第9章才会涉及,Redis基准测试将在第3章介绍,所以本节只对redis-server、redis-cli进行介绍。

1.启动Redis

有三种方法启动Redis:默认配置、运行配置、配置文件启动。(1)默认配置

这种方法会使用Redis的默认配置来启动,下面就是redis-server执行后输出的相关日志:$ redis-server 12040:C 11 Jun 17:28:39.464 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/ to/redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.0.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 12040 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http:// redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 12040:M 11 Jun 17:28:39.470 # Server started, Redis version 3.0.712040:M 11 Jun 17:28:39.470 * The server is now ready to accept connections on port 6379

可以看到直接使用redis-server启动Redis后,会打印出一些日志,通过日志可以看到一些信息,上例中可以看到:

·当前的Redis版本的是3.0.7。

·Redis的默认端口是6379。

·Redis建议要使用配置文件来启动。

因为直接启动无法自定义配置,所以这种方式是不会在生产环境中使用的。(2)运行启动

redis-server加上要修改配置名和值(可以是多对),没有设置的配置将使用默认配置:# redis-server --configKey1 configValue1 --configKey2 configValue2

例如,如果要用6380作为端口启动Redis,那么可以执行:# redis-server --port 6380

虽然运行配置可以自定义配置,但是如果需要修改的配置较多或者希望将配置保存到文件中,不建议使用这种方式。(3)配置文件启动

将配置写到指定文件里,例如我们将配置写到了/opt/redis/redis.conf中,那么只需要执行如下命令即可启动Redis:# redis-server /opt/redis/redis.conf

Redis有60多个配置,这里只给出一些重要的配置(参见表1-3),其他配置会随着不断深入学习进行介绍,第14章会将所有的配置说明进行汇总。表1-3 Redis的基础配置运维提示

Redis目录下都会有一个redis.conf配置文件,里面就是Redis的默认配置,通常来讲我们会在一台机器上启动多个Redis,并且将配置集中管理在指定目录下,而且配置不是完全手写的,而是将redis.conf作为模板进行修改。

显然通过配置文件启动的方式提供了更大的灵活性,所以大部分生产环境会使用这种方式启动Redis。

2.Redis命令行客户端

现在我们已经启动了Redis服务,下面将介绍如何使用redis-cli连接、操作Redis服务。redis-cli可以使用两种方式连接Redis服务器。

·第一种是交互式方式:通过redis-cli-h{host}-p{port}的方式连接到Redis服务,之后所有的操作都是通过交互的方式实现,不需要再执行redis-cli了,例如:redis-cli -h 127.0.0.1 -p 6379127.0.0.1:6379> set hello worldOK127.0.0.1:6379> get hello"world"

·第二种是命令方式:用redis-cli-h ip{host}-p{port}{command}就可以直接得到命令的返回结果,例如:redis-cli -h 127.0.0.1 -p 6379 get hello"world"

这里有两点要注意:1)如果没有-h参数,那么默认连接127.0.0.1;如果没有-p,那么默认6379端口,也就是说如果-h和-p都没写就是连接127.0.0.1:6379这个Redis实例。2)redis-cli是学习Redis的重要工具,后面的很多章节都是用它做讲解,同时redis-cli还提供了很多有价值的参数,可以帮助解决很多问题,有关于redis-cli的强大功能将在第3章进行详细介绍。

3.停止Redis服务

Redis提供了shutdown命令来停止Redis服务,例如要停掉127.0.0.1上6379端口上的Redis服务,可以执行如下操作。$ redis-cli shutdown

可以看到Redis的日志输出如下:客户端发出的命令# User requested shutdown... #shutdown* Saving the final RDB snapshot before exiting.

保存持久化文件有关持久化的特性在节已经进行了简单的介绍,#RDB(Redis1.2是的一种RDBRedis持久化方式 )将文件保存在磁盘上* DB saved on disk #RDB关闭# Redis is now ready to exit, bye bye... #

当使用redis-cli再次连接该Redis服务时,看到Redis已经“失联”。$ redis-cliCould not connect to Redis at 127.0.0.1:6379: Connection refused

这里有三点需要注意一下:

1)Redis关闭的过程:断开与客户端的连接、持久化文件生成,是一种相对优雅的关闭方式。

2)除了可以通过shutdown命令关闭Redis服务以外,还可以通过kill进程号的方式关闭掉Redis,但是不要粗暴地使用kill-9强制杀死Redis服务,不但不会做持久化操作,还会造成缓冲区等资源不能被优雅关闭,极端情况会造成AOF和复制丢失数据的情况。

3)shutdown还有一个参数,代表是否在关闭Redis前,生成持久化文件:redis-cli shutdown nosave|save1.6 Redis重大版本

Redis借鉴了Linux操作系统对于版本号的命名规则:版本号第二位如果是奇数,则为非稳定版本(例如2.7、2.9、3.1),如果是偶数,则为稳定版本(例如2.6、2.8、3.0、3.2)。当前奇数版本就是下一个稳定版本的开发版本,例如2.9版本是3.0版本的开发版本。所以我们在生产环境通常选取偶数版本的Redis,如果对于某些新的特性想提前了解和使用,可以选择最新的奇数版本。

介绍一门技术的版本是很多技术图书的必备内容,通常读者容易忽略,但随着你对这门技术深入学习后,会觉得“备感亲切”,而且通常也会关注新版本的特性,本小节将对Redis发展过程中的一些重要版本及特性进行说明。

1.Redis2.6

Redis2.6在2012年正式发布,经历了17个版本,到2.6.17版本,相比于Redis2.4,主要特性如下:

1)服务端支持Lua脚本。

2)去掉虚拟内存相关功能。

3)放开对客户端连接数的硬编码限制。

4)键的过期时间支持毫秒。

5)从节点提供只读功能。

6)两个新的位图命令:bitcount和bitop。

7)增强了redis-benchmark的功能:支持定制化的压测,CSV输出等功能。

8)基于浮点数自增命令:incrbyfloat和hincrbyfloat。

9)redis-cli可以使用--eval参数实现Lua脚本执行。

10)shutdown命令增强。

11)info可以按照section输出,并且添加了一些统计项。

12)重构了大量的核心代码,所有集群相关的代码都去掉了,cluster功能将会是3.0版本最大的亮点。

13)sort命令优化。

2.Redis2.8

Redis2.8在2013年11月22日正式发布,经历了24个版本,到2.8.24版本,相比于Redis2.6,主要特性如下:

1)添加部分主从复制的功能,在一定程度上降低了由于网络问题,造成频繁全量复制生成RDB对系统造成的压力。

2)尝试性地支持IPv6。

3)可以通过config set命令设置maxclients。

4)可以用bind命令绑定多个IP地址。

5)Redis设置了明显的进程名,方便使用ps命令查看系统进程。

6)config rewrite命令可以将config set持久化到Redis配置文件中。

7)发布订阅添加了pubsub命令。

8)Redis Sentinel第二版,相比于Redis2.6的Redis Sentinel,此版本已经变成生产可用。

3.Redis3.0

Redis3.0在2015年4月1日正式发布,截止到本书完成已经到3.0.7版本,相比于Redis2.8主要特性如下:注意

Redis3.0最大的改动就是添加Redis的分布式实现Redis Cluster,填补了Redis官方没有分布式实现的空白。Redis Cluster经历了4年才正式发布也是有原因的,具体可以参考Redis Cluster的开发日志(http://antirez.com/news/79)。

1)Redis Cluster:Redis的官方分布式实现。

2)全新的embedded string对象编码结果,优化小对象内存访问,在特定的工作负载下速度大幅提升。

3)lru算法大幅提升。

4)migrate连接缓存,大幅提升键迁移的速度。

5)migrate命令两个新的参数copy和replace。

6)新的client pause命令,在指定时间内停止处理客户端请求。

7)bitcount命令性能提升。

8)config set设置maxmemory时候可以设置不同的单位(之前只能是字节),例如config set maxmemory1gb。

9)Redis日志小做调整:日志中会反应当前实例的角色(master或者slave)。

10)incr命令性能提升。

4.Redis3.2

Redis3.2在2016年5月6日正式发布,相比于Redis3.0主要特征如下:

1)添加GEO相关功能。

2)SDS在速度和节省空间上都做了优化。

3)支持用upstart或者systemd管理Redis进程。

4)新的List编码类型:quicklist。

5)从节点读取过期数据保证一致性。

6)添加了hstrlen命令。

7)增强了debug命令,支持了更多的参数。

8)Lua脚本功能增强。

9)添加了Lua Debugger。

10)config set支持更多的配置参数。

11)优化了Redis崩溃后的相关报告。

12)新的RDB格式,但是仍然兼容旧的RDB。

13)加速RDB的加载速度。

14)spop命令支持个数参数。

15)cluster nodes命令得到加速。

16)Jemalloc更新到4.0.3版本。

5.Redis4.0

可能出乎很多人的意料,Redis3.2之后的版本是4.0,而不是3.4、3.6、3.8。一般这种重大版本号的升级也意味着软件或者工具本身发生了重大变革,直到本书截稿前,Redis发布了4.0-RC2,下面列出Redis4.0的新特性:

1)提供了模块系统,方便第三方开发者拓展Redis的功能,更多模块详见:http://redismodules.com。

2)PSYNC2.0:优化了之前版本中,主从节点切换必然引起全量复制的问题。

3)提供了新的缓存剔除算法:LFU(Last Frequently Used),并对已有算法进行了优化。

4)提供了非阻塞del和flushall/flushdb功能,有效解决删除bigkey可能造成的Redis阻塞。

5)提供了RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优势。

6)提供memory命令,实现对内存更为全面的监控统计。

7)提供了交互数据库功能,实现Redis内部数据库之间的数据置换。

8)Redis Cluster兼容NAT和Docker。1.7 本章重点回顾

1)Redis的8个特性:速度快、基于键值对的数据结构服务器、功能丰富、简单稳定、客户端语言多、持久化、主从复制、支持高可用和分布式。

2)Redis并不是万金油,有些场景不适合使用Redis进行开发。

3)开发运维结合以及阅读源码是用好Redis的重要方法。

4)生产环境中使用配置文件启动Redis。

5)生产环境选取稳定版本的Redis。

6)Redis3.0是重要的里程碑,发布了Redis官方的分布式实现Redis Cluster。第2章API的理解和使用

Redis提供了5种数据结构,理解每种数据结构的特点对于Redis开发运维非常重要,同时掌握Redis的单线程命令处理机制,会使数据结构和命令的选择事半功倍,本章内容如下:

·预备知识:几个简单的全局命令,数据结构和内部编码,单线程命令处理机制分析。

·5种数据结构的特点、命令使用、应用场景。

·键管理、遍历键、数据库管理。2.1 预备

在正式介绍5种数据结构之前,了解一下Redis的一些全局命令、数据结构和内部编码、单线程命令处理机制是十分有必要的,它们能为后面内容的学习打下一个好的基础,主要体现在两个方面:第一、Redis的命令有上百个,如果纯靠死记硬背比较困难,但是如果理解Redis的一些机制,会发现这些命令有很强的通用性。第二、Redis不是万金油,有些数据结构和命令必须在特定场景下使用,一旦使用不当可能对Redis本身或者应用本身造成致命伤害。2.1.1 全局命令

Redis有5种数据结构,它们是键值对中的值,对于键来说有一些通用的命令。

1.查看所有键keys *

下面插入了3对字符串类型的键值对:127.0.0.1:6379> set hello worldOK127.0.0.1:6379> set java jedisOK127.0.0.1:6379> set python redis-pyOK

keys*命令会将所有的键输出:127.0.0.1:6379> keys *1) "python"2) "java"3) "hello"

2.键总数dbsize

下面插入一个列表类型的键值对(值是多个元素组成):127.0.0.1:6379> rpush mylist a b c d e f g(integer) 7

dbsize命令会返回当前数据库中键的总数。例如当前数据库有4个键,分别是hello、java、python、mylist,所以dbsize的结果是4:127.0.0.1:6379> dbsize(integer) 4

dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)。而keys命令会遍历所有键,所以它的时间复杂度是O(n),当Redis保存了大量键时,线上环境禁止使用。

3.检查键是否存在exists key

如果键存在则返回1,不存在则返回0:127.0.0.1:6379> exists java(integer) 1127.0.0.1:6379> exists not_exist_key(integer) 0

4.删除键del key [key ...]

del是一个通用命令,无论值是什么数据结构类型,del命令都可以将其删除,例如下面将字符串类型的键java和列表类型的键mylist分别删除:127.0.0.1:6379> del java(integer) 1127.0.0.1:6379> exists java(integer) 0127.0.0.1:6379> del mylist(integer) 1127.0.0.1:6379> exists mylist(integer) 0

返回结果为成功删除键的个数,假设删除一个不存在的键,就会返回0:127.0.0.1:6379> del not_exist_key(integer) 0

同时del命令可以支持删除多个键:127.0.0.1:6379> set a 1OK127.0.0.1:6379> set b 2OK127.0.0.1:6379> set c 3OK127.0.0.1:6379> del a b c(integer) 3

5.键过期expire key seconds

Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,例如为键hello设置了10秒过期时间:127.0.0.1:6379> set hello worldOK127.0.0.1:6379> expire hello 10(integer) 1

ttl命令会返回键的剩余过期时间,它有3种返回值:

·大于等于0的整数:键剩余的过期时间。

·-1:键没设置过期时间。

·-2:键不存在

可以通过ttl命令观察键hello的剩余过期时间:

还剩秒#7127.0.0.1:6379> ttl hello(integer) 7...

还剩秒#1127.0.0.1:6379> ttl hello(integer) 1

返回结果为,说明键已经被删除#-2hello127.0.0.1:6379> ttl hello(integer) -2127.0.0.1:6379> get hello(nil)

有关键过期更为详细的使用以及原理会在2.7节介绍。

6.键的数据结构类型type key

例如键hello是字符串类型,返回结果为string。键mylist是列表类型,返回结果为list:127.0.0.1:6379> set a bOK127.0.0.1:6379> type astring127.0.0.1:6379> rpush mylist a b c d e f g(integer) 7127.0.0.1:6379> type mylistlist

如果键不存在,则返回none:127.0.0.1:6379> type not_exsit_keynone

本小节只是抛砖引玉,给出几个通用的命令,为5种数据结构的使用做一个热身,2.7节将对键管理做一个更为详细的介绍。2.1.2 数据结构和内部编码

type命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合),但这些只是Redis对外的数据结构,如图2-1所示。

实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码,如图2-2所示。

可以看到每种数据结构都有两种以上的内部编码实现,例如list数据结构包含了linkedlist和ziplist两种内部编码。同时有些内部编码,例如ziplist,可以作为多种外部数据结构的内部实现,可以通过object encoding命令查询内部编码:127.0.0.1:6379> object encoding hello"embstr"127.0.0.1:6379> object encoding mylist"ziplist"图2-1 Redis的5种数据结构图2-2 Redis数据结构和内部编码

可以看到键hello对应值的内部编码是embstr,键mylist对应值的内部编码是ziplist。

Redis这样设计有两个好处:第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,例如Redis3.2提供了quicklist,结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对外部用户来说基本感知不到。第二,多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载