读书笔记之《Redis开发与运维》—— 一

迭代极昼
• 阅读 1210

前言

    读书笔记系列主要记录自己看的书籍中的知识点,算是一个归纳整理吧。Redis在我们的日常开发中可以说是很常用了,《Redis开发与运维》
这本书讲解了Redis开发和运维的方方面面,很系统、全面,关键是实用。特来撸撸它,记录一番。全书分为14章,下面将记录个人认为每章中重要的知识点。

一、Redis初识

    Redis是一种基于键值对(key-value)的NoSQL数据库,Redis中的值可以是由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法构成,可以满足很多的应用场景。因为Redis会将所有数据都放在内存里,所以它的读写性能非常好。Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样发生断电或者机器故障,内存中的数据就不会丢失。当然Redis还提供了其他很多附加功能。

1、Redis特性

(1)速度快

Redis的所有数据都是放在内存里的,这是速度快的最主要原因;
Redis是用C语言实现的,“距离”操作系统更近,执行速度相对会更快;
Redis采用单线程架构,预防了多线程可能产生的竞争问题;

(2)基于键值对的数据结构

Redis中的值不仅可以是字符串,还可以是具体的数据结构,方面在不同应用场景的开发。Redis主要提供五种数据结构:字符串、哈希、列表、集合、有序列表,并且在字符串的基础上演变出来了位图(Bitmaps)和HyperLogLog俩种“数据结构”。Redis3.2版本加入了GEO(地理信息定位)的功能。

(3)丰富的功能

除了5种数据结构,还有其他额外的许多功能:

键过期功能,用来实现缓存;
发布订阅功能,用来实现消息系统;
Lua脚本功能,利用Lua脚本创造出新的Redis命令;
简单的事务功能,在一定程度上保证事务特性;
流水线(Pipeline)功能,客户端能将一批命令一次性传到Redis,减少网络开销。

(4)简单稳定

代码少,单线程,服务端、客户端处理简单,redis不依赖操作系统中的类库,自己实现了事件处理的相关功能。

(5)客户端语言多

redis提供了简单的TCP通信协议,很多编程语言可以很方便的接入到redis。

(6)持久化

redis提供了两种持久化方式:RDB和AOF。可以用这两种策略将内存的数据保存在硬盘中,保证了数据的可持久性。

(7)主从复制

redis提供了复制功能,实现了多个相同数据的redis副本,复制功能是分布式redis的基础。

(8)高可用和分布式

redis提供了高可用实现Redis Sentinel(哨兵),能够保证redis节点的故障发现和故障自动转移。并且3.0版本提供了分布式实现Redis Cluster(集群),
这是redis真正的分布式实现,提供了高可用、读写和容量的扩展性。

2、Redis使用场景

缓存、排行榜系统、计数器应用(redis天然支持计数功能,且计数性能很好)、社交网络(粉丝、共同喜好、推送等,社交网站的访问量比较大,传统的关系型数据库不太适合保存这种类型的数据,可用redis实现)、消息队列系统(消息队列具有业务解耦、非实时业务削峰等特性,redis可以满足一般的消息队列功能,不过一般项目中还是使用专业的消息队列,更加强大)。

redis也有不适合它解决的问题场景,站在数据规模和数据冷热角度来分析的话:数据规模角度,数据可分为大规模数据和小规模数据,redis的数据是放在内存里的,如果数据规模非常大,不适合使用redis存储;站在数据冷热角度,数据分为热数据和冷数据,热数据是指需要频繁操作的数据,如果将冷数据放在redis中,浪费内存。

二、API的理解和使用

1、全局命令

(1)查看所有键:keys *

(2)键总数:dbsize

注意:dbsize命令在计算总数时候不会遍历所有键,而是直接获取redis内部的键总数变量,时间复杂度O(1);而keys命令会遍历所有键,时间复杂度O(n),如果redis保存了大量键时,线上环境禁止使用。

(3)检查键是否存在(键存在返回1,不存在返回0):exists key

(4)删除键(返回的结果是成功删除的个数,删除一个不存在的键,返回0):del key [key ...]

注意:del key表示删除一个,del key1 key2 key3表示删除3个

(5)键过期:expire key seconds

注意:redis支持对键添加过期时间,超过过期时间后,会自动删除键;ttl key 命令会返回键的剩余过期时间,返回值>=0表示键的剩余过期时间,返回值-1表示键没有设置过期时间,返回值-2表示键不存在。

(6)键的数据结构类型:type key

注意:如果键是字符串类型,返回string,如果键是列表类型,返回list,其他几种类似。如果键不存在,返回none。

2、数据结构的内部编码

每种数据结构都有自己底层的内部编码实现,而且是多种实现,redis会在合适的场景选择合适的内部编码。比如zset包含skiplist和ziplist两种内部编码。这样设计的好处是:可以改进内部编码,而对外的数据结构和命令没有影响;多种内部编码实现可以在不同场景下发挥各自的优势,比如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这个时候redis会根据配置选项将列表类型的内部实现转换为linkedlist。

3、单线程架构

redis使用单线程架构和I/O多路复用模型来实现高性能的内存数据库服务。一条命令从客户端达到服务端不会立刻执行,所有命令都会进入到一个队列中,然后逐个被执行。不会有两条命令被同时执行。redis使用了I/O多路复用技术来解决I/O的问题。

redis使用单线程模式那么快的原因:纯内存访问,这个最重要;非阻塞I/O,redis使用epoll作为I/O多路复用技术的实现,并且redis加上自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间;单线程避免了线程切换和竞争产生的消耗。

注意:单线程会有一个问题,对于每个命令的执行时间是有要求的,如果执行时间过长,会造成其他命令的阻塞,对于redis来说是致命的,所以redis是面向快速执行场景的数据库。

4、字符串

(1)设置值:set key value [ex seconds] [px milliseconds] [nx|xx]

注意:nx 键必须不存在,才可以设置成功,用于添加; xx 键必须存在,才可以设置成功,用于更新

(2)获取值:get key

批量设置值:mset key value [key value ...]

批量获取值:mget key [key ...]

注意:批量操作可以减少网络时间(n次网络时间+n次命令时间 ---> 1次网络时间+n次命令时间),但是每次批量操作所发送的命令不是无节制的,如果数量过多可能造成redis阻塞或者网络阻塞。

(3)计数:incr key

incr命令用于对值做自增操作,如果值不是整数,返回错误;如果值是整数,返回自增后的结果;如果键不存在,按照值为0自增,返回结果1。

很多存储系统和编程语言内部使用CAS机制实现计数功能,会有一定的CPU开销,但redis中不存在这个问题,因为redis单线程架构,任何命令到了redis服务端都要顺序执行。

(4)内部编码(redis会根据当前值的类型和长度决定使用哪种内部编码实现)

int(8个字节的长整形) embstr(小于等于39个字节的字符串) raw(大于39个字节的字符串)

(5)典型应用场景

缓存功能、计数、共享session、限速

5、哈希

(1)设置值

hset key field value

(2)获取值

hget key field

(3)批量设置或获取field-value

hmget key field [field ...]
hmset key field value [field value ...]

(4)内部编码(ziplist、hashtable)

当哈希类型的field个数小于512,并且所有的value小于64字节,使用ziplist作为哈希的内部实现,否则使用hashtable。512和64是默认的,可以配置。

(5)应用场景

比如:用户信息

6、列表

列表是用来存储多个有序的字符串,可以对列表两端插入和弹出。列表类型有两个特点:(1)列表中的元素是有序的;(2)列表中的元素可以是重复的。

(1)从右端插入、从左端插入

rpush key value [value ...] lpush key value [value ...]

lrange 0 -1 表示从左到右获取列表的所有元素

(2)内部编码(ziplist、linkedlist、quicklist)

当列表的元素个数小于512个,并且列表的每个元素值都小于64字节,redis会选用ziplist来作为列表的内部实现,否则选用linkedlist。Redis3.2版本提供了quicklist内部编码,它是以一个ziplist为节点的linkedlist,结合了ziplist和linkedlist两者的优势。

(3)使用场景

例如:消息队列、文章列表

7、集合

集合中不允许有重复元素,并且集合中的元素是无序的。

(1)添加元素

sadd key elements [elements ...]

(2)删除元素

srem key elements [elements ...]

(3)内部编码(intset、hashtable)

当集合中的元素都是整数且元素个数小于512(默认值,可配置),redis选用intset作为集合内部实现,否则选用hashtable。

(4)使用场景

标签、社交等,比如一个用户对可乐、体育感兴趣,另一个用户对历史、新闻感兴趣,这些兴趣点就是标签。

8、有序集合

不能有重复成员,元素可以排序,每个元素设置一个分数(score)作为排序的依据。有序集合的元素不能重复,但是分数可以重复。

(1)添加成员

zadd key score member [score member ...]

(2)内部编码(ziplist、skiplist)

当有序集合的元素个数小于128个,并且每个元素的值都小于64字节,Redis使用ziplist作为有序集合的内部实现。否则使用skiplist。

(3)使用场景

排行榜系统

9、健管理

(1)单个健管理

返回键类型、键重命名、键过期、迁移键等。

注意:迁移键有三种方式:move、dump+restore、migrate。move命令用于redis内部进行数据迁移,从一个数据库迁移到另一个数据库,不建议生产环境使用redis多数据库功能;dump+restore可以实现在不同redis实例之间进行数据迁移,分为dump和restore两步,其中在源redis上dump会将键值序列化,采用RDB格式,在目标redis上,restore会将上面序列化的值复原;migrate命令用于redis实例之间进行数据迁移,实际上migrate是将dump、restore、del三个命令进行了整合。migrate命令的数据传输直接在源redis和目标redis上完成。

move命令作用于redis实例内部,是原子性的,不支持多个键;dump+restore作用于redis实例之间,不是原子性,不支持多个键;migrate作用于redis实例之间,是原子性的,支持多个键。

(2)遍历键(keys和scan)

keys会全量遍历所有键,可能造成redis阻塞。scan可以想象成只扫描字典中的一部分键,直到将字典中的所有键遍历完毕。scan可以有效解决
keys命令可能产生的阻塞问题,但是scan的过程中,如果有键的变化(增加、删除、修改),就可能新键没有遍历到或者遍历了重复的健。所以scan不能保证完整的遍历出来所有的健。

(3)数据库管理

select dbIndex 切换数据库

flushdb/flushall 清除数据库,flushdb只清除当前数据库,flushall清除所有数据库。

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
Java程序员必须掌握的常用Linux命令。
点击上方蓝色文字关注↑↑↑↑↑!(https://oscimg.oschina.net/oscnet/2ab1caa1208a42049d64b55b0b38f09f.jpg)Java程序员也是半个运维了,在日常开发中经常会接触到Linux环境操作。小公司的开发人员甚至是兼了全运维的工作,下面整理了一些常用的Linux操作命令。
Stella981 Stella981
4年前
Redis 备份、容灾及高可用实战
郝朝阳,宜搜科技,运维工程师,负责前端运维工作。专注于运维自动化的实现。致力于DevOps思想的推广,帮助企业形成形成自有文化的运维体系建设。一,Redis简单介绍Redis是一个高性能的keyvalue非关系型数据库,由于其具有高性能的特性,支持高可用、持久化、多种数据结构、集群等,使其脱颖而出,成为常用的非关系型数据库。此
Stella981 Stella981
4年前
Kubernetes operator 模式开发实践
0\.前言近日我们在开发符合我们业务自身需求的微服务平台时,使用了Kubernetes的OperatorPattern来实现其中的运维系统,在本文,我们将实现过程中积累的主要知识点和技术细节做了一个整理。读者在阅读完本文之后,会对OperatorPattern有一个基本的了解,并能将该模式应用到自己的业务中去。除此
Stella981 Stella981
4年前
Redis migrate 数据迁移工具
在工作中可能会遇到单点Redis向Redis集群迁移数据的问题,但又不能老麻烦运维来做。为了方便研发自己迁移数据,我这里写了一个简单的Redis迁移工具,希望对有需要的人有用。本工具支持:单点Redis到单点Redis迁移单点Redis到Redis集群迁移Redis集群到Redis集群迁移Redis集群
Wesley13 Wesley13
4年前
NoSQL从小白到码神 火推08
NoSQL从小白到码神本课程适用于运维、开发相关人员。课程目录:NoSQL背景NoSQL简介NoSQL和关系型数据库对比Redis简介Redis下载安装配置(Linux环境)Redis优点
Stella981 Stella981
4年前
DOIS 2019 DevOps国际峰会北京站来袭~
DevOps国际峰会是国内唯一的国际性DevOps技术峰会,由OSCAR 联盟指导、DevOps时代社区与高效运维社区联合主办,共邀全球80余名顶级专家畅谈DevOps体系与方法、过程与实践、工具与技术。会议召开时间:2019070508:00至2019070618:00结束会议召开地点:北京主办单位:DevOps
Stella981 Stella981
4年前
Linux运维常见面试题之精华收录
Linux运维常见面试题之精华收录1、什么是运维?什么是游戏运维?1)运维是指大型组织已经建立好的网络软硬件的维护,就是要保证业务的上线与运作的正常,在他运转的过程中,对他进行维护,他集合了网络、系统、数据库、开发、安全、监控于一身的技术运维又包括很多种,有DBA运维、网站运维、虚
Stella981 Stella981
4年前
Redis4.0新特性(二)
Redis4.0新增了非常实用的lazyfree特性,从根本上解决BigKey(主要指定元素较多集合类型Key)删除的风险。笔者在redis运维中也遇过几次BigKey删除带来可用性和性能故障。本文分为以下几节说明redislazyfree:lazyfree的定义我们为什么需要lazyfreelazyfr
初识DevOps
基本概念和延伸的思考DevOps,是Development(开发)和Operations(运维)组成的复合词,一般译为“开发运维一体化”。看到这个概念,首先会产生几个问题:开发是什么,哪些环节是开发?运维是什么,哪些环节是运维?开发人员写好代码在本地调试,环境出问题了自己来调整,这是开发工作还是运维工作?系统故障后,运维人员发现是配置文件内容出错了就改成了正
陈哥聊测试 陈哥聊测试
1年前
DevOps和它的朋友们——聊聊其他 “Ops”(一)
DevOps不仅仅是将敏捷开发概念与IT运维相结合,还简化了在云环境中开发和部署应用程序的过程。