《Redis开发与运维》读书笔记(一)Redis简介

第一章 Redis简介

1.1 什么是Redis?

Redis是一种基于键值对的NoSQL(非关系型)数据库。与另外一些键值对数据库不同的是,Redis的值可以是:string、hash、list、set、zset(有序集合)、Bitmaps(位图)、HyperLogLog(做基数统计)、GEO(地理信息定位)等多种数据结构和算法。

Redis主要有哪些优势?

  • 值可以存放多种数据结构和算法,所以可以满足大量的应用场景。
  • 将数据存放在内存,所以有高效的读写性能。
  • 内存中的数据通过快照和日志的方式保存在硬盘上,防止丢失。

Redis的作者本身想通过MySql来实现一个高性能的队列功能,但优化SQL无法提高性能,所以他决定自己开发一款数据库,即Redis。目前大部分国内外知名的互联网企业都在使用Redis,还有一些开源技术如ELK(即Elasticsearch,Logstash 和Kibana,实现集中式日志系统)也把Redis当作组件中的重要一环。


1.2 Redis特性

1.2.1 速度快

Redis速度非常快,其高效性能的原因有:

  • 所有数据都存放在内存。
  • 使用C语言实现。
  • 使用单线程架构,避免了多线程竞争问题。
  • 作者对源码进行了精打细磨,曾被人评价是少有的集性能与优雅于一身的开源代码。

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

大部分语言都会提供类似字典的功能,映射这种组织数据的方式叫做基于键值的方式,但Redis中的值不仅可以是字符串,还可以是字符串、哈希、列表、集合、有序集合。同时又在字符串的基础上演变出了Bitmaps(位图)、HyperLogLog(做基数统计)两种高级数据结构,并且随着LBS(Location Based Service,基于位置服务)的发展加入了GEO(地理信息定位)功能。

1.2.3 丰富的功能

Redis还提供许多额外功能:

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

1.2.4 简单稳定

Redis的简单主要体现在三个方面:

  • 首先是源码很精简,几万行代码,对于大部分使用者来说都是可以去快速阅读一遍的。
  • 其次Redis使用单线程模型,不仅使得Redis服务端处理模型变得简单,也使客户端开发变得简单。
  • 最后Redis不需要依赖操作系统的类库(如Memcache需要依赖libevent),Redis自己实现了事件处理的相关功能。

Redis虽然精简,但非常稳定。

1.2.5 客户端语言多

Redis提供了简单的TCP通信协议,方便编程语言接入Redis,因为主流公司的认可,所以大部分客户端编程语言都支持Redis。

1.2.6 持久化

数据存放在内存一般被认为是不安全的(断电或机器故障导致数据丢失),Redis提供了两种持久化方式:RDBAOF

1.2.7 主从复制

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

1.2.8 高可用和分布式

Redis从2.8版本后提供了高可用实现:Redis Sentinel,能保证Redis节点的故障发现和故障自动转移。

3.0版本正式提供了分布式实现:Redis Cluster,提供了高可用、读写和容量的扩展性。


1.3 Redis使用场景

1.3.1 Redis可以做什么?

  1. 缓存,常用于大型网站来加速数据访问和缓解后端数据库压力。Redis提供了键值过期时间设置,也提供了灵活控制最大内存和内存溢出后的淘汰策略。
  2. 排行榜系统,几乎所有网站都需要各种规则的排行榜,或是依据热度排行,或是发布时间,或是结合各种复杂维度计算。Redis提供了列表和有序集合数据结构,合理的使用这些结构可以很方便的构建各种排行榜系统。
  3. 计数器应用,如一些视频网站的播放数,电商网站的浏览数,对于数据的实时性有较高的要求,如果并发量很大时,传统关系型数据库很难做好这一工作。Redis天然支持计数功能,且性能优越。
  4. 社交网络,比如赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等常见功能,由于社交网站访问量通常较大,且传统关系型数据库不太适合存储这种类型的数据,而Redis提供的数据结构比较容易实现这些功能。
  5. 消息队列系统,大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列功能,虽然相比专业的消息队列还有所欠缺,但可以满足大部分基础需求。

1.3.2 Redis不可以做什么?

正像大部分技术一样,Redis也有其边界。

首先站在数据规模的角度来看,我们把数据分为大规模数据和小规模数据。因为其存放数据于内存这一设定,在面对海量数据时就是一个性价比极低的选择。

然后站在数据冷热的角度来看,我们把数据分为热数据和冷数据,热数据指需要频繁操作的数据,冷数据则相反。例如对于视频网站,视频基本信息需要在各个业务线频繁操作,而用户观看记录(不要和观看数混为一谈,此处应该指行为数据)相比就不会那么繁忙,先不讨论两者的规模差异,视频信息属于热数据,用户观看记录属于冷数据。冷数据存放于内存是一种浪费,而热数据可以放在内存中加速读写,也减轻了后端存储的负载压力。


1.4 如何用好Redis?

  • 不要把Redis当作黑盒使用,开发和运维一样重要。很多线上故障都是因为开发者把Redis当作黑盒使用而造成的:如果不了解Redis的单线程模型,可能会在有上千万个键的Redis上执行 keys * 操作;如果不了解持久化相关原理,可能会在一个写操作量很大的Redis上配置自动保存RDB。相比专职的关系型数据库DBA,大部分公司并没有人来专职运维Redis,所以往往需要开发人员来担当这一角色。这一经验对于我们学好Redis也大有帮助。
  • 阅读源码。Redis源码量很小,所以请多读Redis源码,不仅可以加深理解,也可以提高自身编程水平,甚至定制化Redis,需要大公司会对Redis进行定制来满足其业务需求。

1.5 安装Redis

1.5.1 Linux上安装Redis

Linux上安装Redis的方式有两种:

  • 第一种是通过各个操作系统的软件管理软件进行安装,如CentOS的yum管理工具,Ubuntu的apt(Docker应该也属于第一种吧)。
  • 第二种是通过源码的方式安装。Redis更新较快,所以一般推荐第二种安装方式。

安装步骤只需要六步即可,如下案例安装3.0.7版本。

1
2
3
4
5
6
$ 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(为了不把redis目录固定在指定版本,有利于未来版本升级,算是一种安装软件的好习惯)。
  4. 进入redis目录。
  5. 编译(编译前确保操作系统已安装gcc)。
  6. 安装(将Redis的相关运行软件放在/usr/local/bin/下,从而可以在任意目录下执行Redis的命令)。

如下图安装5.0.8版本。

1.5.2 Windows上安装Redis

Redis官方并不支持Windows操作系统,但微软的开源技术组在GitHub上维护了一个Redis的分支:microsoftarchive/redis

  • 首先在上述开源项目中找到想要安装的版本并下载:https://github.com/MSOpenTech/redis/releases
  • 解压并在根目录打开命令行,可以把redis路径添加到环境变量,方便以后使用。

1.5.3 配置、启动、操作、关闭Redis

Redis安装后,src和 /usr/local/bin/ 下会多出几个redis开头的文件,被称作Redis Shell。类似于JDK中的可执行文件,这些文件可以帮助我们做很多事情。

可执行文件 作用
redis-server 启动Redis
redis-cli Redis命令行客户端
redis-benchmark Redis基准测试工具
redis-check-aof Redis AOF持久化文件检查和修复工具
redis-check-dump Redis RDB持久化文件检查和修复工具
redis-sentinel 启动Redis Sentinel

1. 启动Redis

首先启动Redis,有三种方式:默认配置、运行配置、配置文件启动。

(1)默认配置
1
$ redis-server

由上述信息可以得知,我们当前版本是5.0.8,默认端口6379,线程ID-30710,Redis建议使用配置文件启动。因为直接启动无法自定义配置,所以生产环境不会采用这种方式。

(2)运行配置

redis-server要加上修改配置名和值(可以多对),没有配置的将使用默认配置。

1
$ redis-server --configkey1 configValue1 --configkey2 configValue2

比如我们想修改端口号。

1
$ redis-server --port 6380

当配置较多或是想保存配置到文件中时,不建议使用这种方式。

(3)配置文件启动

将配置写到文件中,比如写到 /opt/redis/redis.conf ,然后只须执行下列命令即可启动Redis。

1
$ redis-server /opt/redis/redis.conf

Redis有60多个配置,此处只给出比较重要的四个,后续会专门做整理介绍。

配置名 配置说明
port 端口
logfile 日志文件
dir Redis工作目录(存放持久化文件和日志文件)
daemonize 是否以守护线程的方式启动Redis

配置文件启动的方式具有灵活性,所以大部分生产环境会使用这种方式。

2. Redis命令行客户端

我们已经启动了Redis服务,接下来是使用 redis-cli 连接和操作Redis服务。redis-cli 有两种方式来连接Redis服务器。

(1)交互式方式

通过 redis-cli -h {host} -p {port} 的方式连接到Redis服务,之后所有的操作都通过交互的方式实现,不需要再执行 redis-cli 。

1
$ redis-cli -h 127.0.0.1 -p {port}  

(2)命令方式

通过 redis-cli -h {host} -p {port} {command} 直接得到命令结果。

没有 -h 参数则默认连接127.0.0.1;没有 -p 参数则默认6379端口。

3. 停止Redis服务

Redis提供了shutdown命令来停止Redis服务。

1
$ redis-cli shutdown

需要注意:

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

  2. 除了shutdown命令外,也可以通过kill进程号的方式关闭Redis,但请不要粗暴的使用 kill -9 强制杀死Redis服务,这样不但不会做持久化操作,还会造成缓冲区不能正常关闭,极端情况下会造成AOF和复制丢失数据的情况。

  3. shutdown还有一个参数,表示是否在关闭Redis前生成持久化文件。

    1
    $ redis-cli shutdown nosave|save

1.6 版本命名

Redis借鉴了Linux对于版本号的命名规则:版本号第二位如果是奇数,表示非稳定版本(unstable),如果是偶数,表示稳定版本(stable),当然还有Beta版本。


参考:

🔗 《Redis开发与运维》