1.Redis 简介
Redis是一个开源的高性能键值对数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,并借助许多高层级的接口使其可以胜任如缓存、队列系统等不同的角色。本章将分别介绍Redis的历史和特性,以使读者能够快速地对Redis有一个全面的了解。
1.历史与发展
2008年,意大利的一家创业公司Merzia.推出了一款基于MySQL的网站实时统计系统LLOOGG ,然而没过多久该公司的创始人Salvatore Sanfilippo便开始对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望让更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查 ,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁和知乎,国外如GitHub、Stack Overflow、Flickr、暴雪和Instagram,都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发,Salvatore Sanfilippo和Pieter Noordhuis也分别于同年的3月和5月加入VMware,全职开发Redis。
2.特点
作为一款个人开发的数据库,Redis究竟有什么魅力吸引了如此多的用户呢?
以字典结构存储数据
允许通过TCP协议读取字典的内容
强大的缓存系统, 可以为每个键设置TTL, 以及按照一定规则自动淘汰不需要的键
支持使用列表的形式构造任务队列
数据存储在内存中也可以持久化到硬盘
2.1存储结构
有过脚本语言编程经验的读者对字典(或称映射、关联数组)数据结构一定很熟悉,如代码dict["key"]="value"中dict是一个字典结构变量,字符串"key"是键名,而"value"是键值,在字典中我们可以获取或设置键名对应的键值,也可以删除一个键。Redis是REmote DIctionary Server(远程字典服务器)的缩写,它以字典结构存储数据,并允许其他应用通过TCP协议读写字典中的内容。同大多数脚本语言中的字典一样,Redis字典中的键值除了可以是字符串,还可以是其他数据类型。到目前为止Redis支持的键值数据类型如下:
-
字符串类型
-
散列类型
-
列表类型
-
集合类型
-
有序集合类型
这种字典形式的存储结构与常见的MySQL 等关系数据库的二维表形式的存储结构有很大的差异。举个例子,如下所示,我们在程序中使用post变量存储了一篇文章的数据(包括标题、正文、阅读量和标签):
post["title"]="Hello World!" post["content"]="Blablabla..." post["views"]=0 post["tags"]=["Python","Django","Flask"]
现在我们希望将这篇文章的数据存储在数据库中,并且要求可以通过标签检索出文章。如果使用关系数据库存储,一般会将其中的标题、正文和阅读量存储在一个表中,而将标签存储在另一个表中,然后使用第三个表连接文章和标签表 。需要查询时还得将三个表进行连接,不是很直观。而Redis字典结构的存储方式和对多种键值数据类型的支持使得开发者可以将程序中的数据直接映射到Redis中,数据在Redis中的存储形式和其在程序中的存储方式非常相近。使用Redis的另一个优势是其对不同的数据类型提供了非常方便的操作方式,如使用集合类型存储文章标签,Redis可以对标签进行如交集、并集这样的集合运算操作。后文会专门介绍如何借助集合运算轻易地实现“找出所有同时属于A标签和B标签且不属于C标签”这样关系数据库实现起来性能不高且较为繁琐的操作。
2.2内存存储与持久化
Redis数据库中的所有数据都存储在内存中。由于内存的读写速度远快于硬盘,因此Redis在性能上对比其他基于硬盘存储的数据库有非常明显的优势,在一台普通的笔记本电脑上,Redis可以在一秒内读写超过十万个键值。
将数据存储在内存中也有问题,例如,程序退出后内存中的数据会丢失。不过 Redis提供了对持久化的支持,即将可以内存中的数据异步写入到硬盘中,同时不影响继续提供服务。
2.3功能丰富
Redis虽然是作为数据库开发的,但由于其提供了丰富的功能,越来越多的人将其用作缓存、队列系统等。Redis可谓是名副其实的多面手。
Redis可以为每个键设置生存时间(Time To Live,TTL),生存时间到期后键会自动被删除。这一功能配合出色的性能让Redis可以作为缓存系统来使用,而且由于Redis支持持久化和丰富的数据类型,使其成为了另一个非常流行的缓存系统Memcached的有力竞争者。
讨论 关于Redis和Memcached优劣的讨论一直是一个热门的话题。在性能上Redis是单线程模型,而Memcached支持多线程,所以在多核服务器上后者的性能更高一些。然而,前面已经介绍过,Redis的性能已经足够优异,在绝大部分场合下其性能都不会成为瓶颈。所以在使用时更应该关心的是二者在功能上的区别,如果需要用到高级的数据类型或是持久化等功能,Redis将会是Memcached很好的替代品。
作为缓存系统,Redis还可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定的规则自动淘汰不需要的键。
除此之外,Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易地实现一个高性能的优先级队列。同时在更高层面上,Redis还支持“发布/订阅”的消息模式,可以基于此构建聊天室等系统。
2.4简单稳定
即使功能再丰富,如果使用起来太复杂也很难吸引人。Redis直观的存储结构使得通过程序与Redis交互十分简单。在Redis中使用命令来读写数据,命令语句之于Redis就相当于SQL语言之于关系数据库。例如在关系数据库中要获取posts表内id为1的记录的title字段的值可以使用如下SQL语句实现:
SELECT title FROM posts WHERE id=1 LIMIT 1
相对应的,在Redis中要读取键名为post:1的散列类型键的title字段的值,可以使用如下命令语句实现:
HGET post:1 title
其中HGET就是一个命令。Redis提供了一百多个命令,听起来很多,但是常用的却只有十几个,并且每个命令都很容易记忆。读完第3章你就会发现Redis的命令比SQL语言要简单很多。
Redis提供了几十种不同编程语言的客户端库,这些库都很好地封装了Redis的命令,使得在程序中与Redis进行交互变得更容易。有些库还提供了可以将编程语言中的数据类型直接以相应的形式存储到Redis中(如将数组直接以列表类型存入Redis)的简单方法,使用起来非常方便。
读者可以在http://redis.io/commands
上查看到所有的redis命令和使用方法
Redis使用C语言开发,代码量只有3万多行。这降低了用户通过修改Redis源代码来使之更适合自己项目需要的门槛。对于希望“榨干”数据库性能的开发者而言,这无疑是一个很大的吸引力。
Redis 是开源的,所以事实上Redis的开发者并不止Salvatore Sanfilippo和Pieter Noordhuis。截至目前,有将近100名开发者为Redis贡献了代码。良好的开发氛围和严谨的版本发布机制使得Redis的稳定版本非常可靠,如此多的公司在项目中使用了Redis也可以印证这一点。
小结
本章是redis简介,有如下核心知识点
- 了解redis存储结构
- 了解redis特性
- Redis安装
学习Redis最好的办法就是动手尝试它。在介绍Redis最核心的内容之前,本章先来介绍一下如何安装和运行Redis,以及Redis的基础知识,使读者可以在之后的章节中一边学习一边实践。
window安装Redis
安装Redis是开始Redis学习之旅的第一步。在安装Redis前需要了解Redis的版本规则以选择最适合自己的版本,Redis约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如2.4版、2.6版),奇数版本是非稳定版(如2.5版、2.7版),推荐使用稳定版本进行开发和在生产环境使用。
-
下载
-
window安装
(网盘链接:https://pan.baidu.com/s/1ymxRgUX_mja_fmvqeBH3GA 提取码:love
-
Centos安装
-
安装
-
直接解压即可
img
- 双击打开redis-server.exe启动服务端
- 双击打开redis-cli.exe启动客户端工具
-
文件说明
image-20201215165832969 -
redis-benchmark.exe 测redis性能的程序,可以同时模拟N多客户端查询和赋值
-
redis-check-aof.exe 更新日志检查–修复日志
-
redis-check-dump.exe 本地数据库检查
-
redis.conf redis配置文件redis-cli.exe 客户端连接 redis服务器工具
-
redis-server.exe redis服务器启动程序
-
可把redis添加为系统服务,设置为开机启动步骤如下
-
打开cmd指令窗口
-
输入你刚才解压的文件路径
-
然后输入redis-server redis.windows.conf 命令
img
接下来部署Redis为windows下的服务 首先关掉上一个窗口再打开一个新的cmd命令窗口
然后输入指令redis-server --service-install redis.windows.conf
随后,进入右击此电脑–管理–服务和应用程序–服务 启动服务
img
Redis常用的指令 卸载服务:redis-server --service-uninstall 开启服务:redis-server --service-start 停止服务:redis-server --service-stop 测试redis,通过cd到我们解压的目录,输入指令通过Set get指令查看是否成功
image-20201215164430963
图形客户端
百度链接:https://pan.baidu.com/s/10LQ9tvj8bIUECe4E3f4xpw 提取码:love
Linux安装
redis源码 http://download.redis.io/redis-stable.tar.gz下载。
下载安装包后解压即可使用make 命令完成编译,完整的命令如下:
1.升级GCC
Linux一般默认GCC版本是4.8.5,Redis新版本使用了更高版本的GC
`$ gcc -v # 查看gcc版本
$ yum -y install centos-release-scl # 升级到9.1版本
$ yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
$ scl enable devtoolset-9 bash
以上为临时启用,如果要长期使用gcc 9.1的话
$ echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile`
2.源码安装
`wget http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
make install # 默认会安装到/usr/local/bin 目录下
make && make PREFIX=/usr/local/redis install #(不想安装到认目录,可用 PREFIX 指定了安装目录)`
redis安装在/usr/local/bin/
目录
# redis可执行文件(因为配置了redis的环境变量,redis/bin中的所有命令都可被识别) redis-server #Redis服务器 redis-cli #Redis命令行客户端 redis-benchmark #Redis性能测试工具 redis-check-aof #AOF文件修复工具 redis-check-dump #RDB文件检测工具 redis-sentinel #Sentinel 服务器
3.启动
#三种启动方式 cd /usr/local/bin ./redis-server 默认端口6379 ./redis-server --port 端口号 ./redis-server /path/to/redis.conf 启动时的配置文件将覆盖系统同名配置项
4.更改配置
复制安装目录中的redis.conf作为配置文件,将其拷贝到/usr/local/etc
目录,以后运行redis服务,就指定该配置文件。
`mkdir -p /usr/local/etc # 创建配置文件夹
cd /usr/local/redis-stable
cp redis.conf /usr/local/etc/ #拷贝
更改配置
cd /usr/local/etc/
vi redis.conf
开启守护进程(表明reids启动后在后台运行)
daemonize yes
启动
cd /usr/local/bin
./redis-server /usr/local/etc/redis.conf # 后台启动`
5.配置redis环境变量
`# 编辑 /etc/profile
vi /etc/profile
在配置文件中添加环境变量
export REDIS_HOME=/usr/local # redis安装目录
export PATH=$PATH:$REDIS_HOME/bin
重新编译配置文件
. /etc/profile
现在可以直接识别redis指令了
redis-server /usr/local/etc/redis.conf # 启动
redis-cli # 连接
redis-cli shutdown # 关闭`
- 常见命令
`# 检查服务是否正常启动
ps -ef | grep redis
ping命令检查连接是否正常,正常就会收到PONG
redis-cli ping
正常关闭服务
redis-cli shutdown
手启服务时指定配置文件,(前面默认配置在/usr/local/etc/redis.conf)
redis-server /usr/local/etc/redis.conf
通过-h和-p参数指定IP和端口信息
redis-cli -h 127.0.0.1 -p 6380`
8.redis中指令
`redis 127.0.0.1:6379> info #查看server版本内存使用连接等信息
redis 127.0.0.1:6379> client list #获取客户连接列表
redis 127.0.0.1:6379> client kill 127.0.0.1:33441 #终止某个客户端连接
redis 127.0.0.1:6379> dbsize #当前保存key的数量
redis 127.0.0.1:6379> save #立即保存数据到硬盘
redis 127.0.0.1:6379> bgsave #异步保存数据到硬盘
redis 127.0.0.1:6379> flushdb #当前库中移除所有key
redis 127.0.0.1:6379> flushall #移除所有key从所有库中
redis 127.0.0.1:6379> lastsave #获取上次成功保存到硬盘的unix时间戳
redis 127.0.0.1:6379> monitor #实时监测服务器接收到的请求
redis 127.0.0.1:6379> slowlog len #查询慢查询日志条数
(integer) 3
redis 127.0.0.1:6379> slowlog get #返回所有的慢查询日志,最大值取决于slowlog-max-len配置
redis 127.0.0.1:6379> slowlog get 2 #打印两条慢查询日志
redis 127.0.0.1:6379> slowlog reset #清空慢查询日志信息`
注意:不能强制关闭redis服务器,会丢失数据,正常关闭指令是shutdow
参考文档:
http://blog.csdn.net/love__coder/article/details/8271832
常用配置
以上redis的配置文件在/usr/local/etc/redis.conf
中
`# 1. 端口号 默认为6379
prot 6379
bind 127.0.0.1 # 绑定IP地址,只允许来自指定网卡的Redis请求,如果想允许任意地址访问将 bind 注释掉就行
设置Redis连接密码,默认无,如果配置了连接密码,客户端在连接Redis时需要通过【AUTH 】命令提供密码
requirepass 123456
设置最大客户端连接数。 默认为10000,最大值为当前'file limit - 32'
如果连接数用完了,新客户端连接时会报 'max number of clients reached'
maxclients 10000
指定Redis最大内存限制, Redis在启动时会把数据加载到内存中,
达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,
当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。
maxmemory
在内存达到上限后的处理策略
1. volatile-lru -> 回收 最久 没有使用的键(近似 LRU),但仅限于在过期集合的键。
2. allkeys-lru -> 所有键中回收 最久 使用的键(近似 LRU)。
3. volatile-lfu -> 回收使用 频率最少 的键(近似 LFU),但仅限于在过期集合的键。
4. allkeys-lfu -> 所有键中回收使用 频率最少 的键(近似 LFU)。
5. volatile-random -> 回收 随机 的键,但仅限于在过期集合的键。
6. allkeys-random -> 所有键中回收 随机 的键。
7. volatile-ttl ->回收在过期集合的键,并且 优先回收存活时间(TTL)较短 的键。
8. noeviction -> 直接返回错误,当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)。
默认是没有开启AOF(append only file)方式持久化,可以通过appendonly参数启用
appendonly true
目录和RDB文件目录一样,默认文件名是appendonly.aof,可通过append filename参数修改:
appendfilename "appendonly.aof"
由于操作系统的缓存机制,数据并没有立即写入硬盘,而是进入了硬盘的缓存,默认系统每30秒会执行一次同步操作,以将缓存中的数据真正地写入硬盘,在这30的过程中如果异常退出则会导制硬盘缓存中的数据丢失,设置同步的时机:
appendfsync always #每次修改同步一次
appendfsync everysec #每秒同步一次
appendfsync no #no表示交同操作系统来做即30秒一次。
设置AOF文件的重写
BGREWRITEAOF命令手动执行AOF重写
当目前的AOF文件大小超过上一次重写时的大少的百分之多少时会进行重写,如果之前没有重写,则以启动进的大小为依据
auto-aof-rewrite-percentage 100
限制允许重写的最小AOF文件大小
auto-oaf-rewrite-min-size 60mb
aof-load-truncated的默认值为 yes。当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。
如果是no,用户必须手动redis-check-aof修复AOF文件才可以重启Redis服务器。
aof-load-truncated yes
对于 persistence 持久化存储,Redis 有两种持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。其中RDB是一份内存快照,AOF则为可回放的命令日志,他们各有特点也相互独立。4.0开始允许使用RDB-AOF混合持久化的方式,结合了两者的优点,通过 aof-use-rdb-preamble 配置项可以打开混合开关。
表示是否开启混合存储,默认是开启的。
开启后Redis保证RDB转储跟AOF重写不会同时进行。
当Redis启动时,即便RDB和AOF持久化同时启用且AOF,RDB文件都存在,则Redis总是会先加载AOF文件,这是因为AOF文件被认为能够更好的保证数据一致性。
aof-use-rdb-preamble yes`
命令行设置密码(重启后失效)
redis 127.0.0.1:6379> config set requirepass 123456
密码验证:
127.0.0.1:6379> auth 123456
查询密码:
redis 127.0.0.1:6379> config get requirepass
登录有密码的Redis,在登录的时候加上密码参数
redis-cli -p 6379 -a 123456
AUTH命令跟其他redis命令一样,是没有加密的;阻止不了攻击者在网络上窃取你的密码;
小结
本章主要介绍redis如何安装
- 掌握window和linux安装步骤
- 会启动和连接redis
- Redis命令行客户端
redis-cli(Redis Command Line Interface)是Redis自带的基于命令行的Redis客户端,也是我们学习和测试Redis的重要工具,本书后面会使用它来讲解Redis各种命令的用法。
本节将会介绍如何通过redis-cli向Redis发送命令,并且对Redis命令返回值的不同类型进行简单介绍。
发送命令
通过 redis-cli向Redis发送命令有两种方式,第一种方式是将命令作为redis-cli的参数执行,比如在2.2.2节中用过的redis-cli SHUTDOWN。redis-cli执行时会自动按照默认配置(服务器地址为127.0.0.1,端口号为6379)连接Redis,通过-h和-p参数可以自定义地址和端口号:
redis-cli -h 127.0.0.1 -p 6379
Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG。如:
redis-cli PING PONG
第二种方式是不附带参数运行redis-cli,这样会进入交互模式,可以自由输入命令,例如:
redis-cli redis 127.0.0.1:6379> PING PONG redis 127.0.0.1:6379> ECHO hi "hi"
这种方式在要输入多条命令时比较方便,也是本书中主要采用的方式。为了简便起见,后文中我们将用redis>表示redis 127.0.0.1:6379>。
命令返回值
命令的返回值有5种类型,对于每种类型redis-cli的展现结果都不同,下面分别说明。
1.状态回复
状态回复(status reply)是最简单的一种回复,比如向Redis发送SET命令设置某个键的值时,Redis会回复状态OK表示设置成功。另外之前演示的对PING命令的回复PONG也是状态回复。状态回复直接显示状态信息,例如: