redis入门初学知识
一、 Redis 介绍
Remote Dictionary Server(Redis)是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map),列表(list), 集合(sets) 和 有序集合(sorted sets)。redis可以是纯内存数据库,也可以将数据记录到磁盘进行持久化。
二、 Redis 常用应用场景
1、最常用的就是会话缓存
2、消息队列,比如支付
3、活动排行榜或计数
4、发布、订阅消息(消息通知)
5、商品列表、评论列表等
三、 Redis的配置
redis的配置文件,你会发现还是很有条理的。redis配置文件被分成了几大块区域,它们分别是:
1.通用(general)
2.快照(snapshotting)
3.复制(replication)
4.安全(security)
5.限制(limits)
6.追加模式(append only mode)
7.LUA脚本(lua scripting),暂时不写
8.慢日志(slow log)
9.事件通知(event notification),暂时不写
1.通用:
通过daemonize配置项可以控制redis的运行形式,默认是no(打开客户端才会运行,关闭客户端redis停止运行),如果改为yes,那么redis就会以daemon形式运行(即后台运行,我们应该使用这种形式):
daemonize yes
当以daemon形式运行时,redis会生成一个pid文件,默认会生成在/var/run/redis.pid。当然,你可以通过pidfile来指定pid文件生成的位置
pidfile /path/to/redis.pid
默认绑定127.0.0.1,redis会响应本机所有可用网卡的连接请求。当然,redis允许你通过bind配置项来指定要绑定的IP,我们可以绑定一个或多个ip,比如我们绑定192.168.100.2,那么192.168.100这个网段的都可以访问(这个最好是内网网段),也可看下这篇文章(ttps://bingozb.github.io/62.html)
bind 127.0.0.1
redis的默认服务端口是6379,你可以通过port配置项来修改。如果端口设置为0的话,redis便不会监听端口了。
port 6379
“如果redis不监听端口,还怎么与外界通信呢”,其实redis还支持通过unix socket方式来接收请求。可以通过unixsocket配置项来指定unix socket文件的路径,并通过unixsocketperm来指定文件的权限。
unixsocket /tmp/redis.sock
unixsocketperm 755
当一个redis-client一直没有请求发向server端,那么server端有权主动关闭这个连接,可以通过timeout来设置“空闲超时时限”,0表示永不关闭。
timeout 0
TCP连接保活策略,可以通过tcp-keepalive配置项来进行设置,单位为秒,假如设置为60秒,则server端会每60秒向连接空闲的客户端发起一次ACK请求,以检查客户端是否已经挂掉,对于无响应的客户端则会关闭其连接。所以关闭一个连接最长需要120秒的时间。如果设置为0,则不会进行保活检测。
tcp-keepalive 300
redis支持通过loglevel配置项设置日志等级,共分四级,即debug、verbose、notice、warning。
loglevel notice
redis也支持通过logfile配置项来设置日志文件的生成位置。如果设置为空字符串,则redis会将日志输出到标准输出。假如你在daemon情况下将日志设置为输出到标准输出,则日志会被写到/dev/null中。
logfile ""
如果希望日志打印到syslog中,也很容易,通过syslog-enabled来控制。另外,syslog-ident还可以让你指定syslog里的日志标志
syslog-ident redis
对于redis来说,可以设置其数据库的总数量,默认包含16个数据库,这16个数据库的编号将是0到15。默认的数据库是编号为0的数据库。用户可以使用select <DBid>来选择相应的数据库:
databases 16
2.快照--rdb(redis持久化方法之一):
快照是默认的持久化方式,我们可以用如下的指令来让数据保存到磁盘上,即控制RDB快照功能:
save 900 1 //表示每15分钟且至少有1个key改变,就触发一次持久化
save 300 10 //表示每5分钟且至少有10个key改变,就触发一次持久化
save 60 10000 //表示每60秒至少有10000个key改变,就触发一次持久化
如果你想禁用RDB持久化的策略,只要不设置任何save指令就可以,或者给save传入一个空字符串参数也可以达到相同效果,就像这样:
save ""
如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求。这样做的好处在于可以让用户很明确的知道内存中的数据和磁盘上的数据已经存在不一致了。如果redis不顾这种不一致,一意孤行的继续接收写请求,就可能会引起一些灾难性的后果。如果下一次RDB持久化成功,redis会自动恢复接受写请求。当然,如果你不在乎这种数据不一致或者有其他的手段发现和控制这种不一致的话,你完全可以关闭这个功能,以便在快照写入失败时,也能确保redis继续接受新的写请求。配置项如下:
stop-writes-on-bgsave-error yes
对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大
rdbcompression yes
在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果你希望获取到最大的性能提升,可以关闭此功能。
rdbchecksum yes
我们还可以设置快照文件的名称,默认是这样配置的:
dbfilename dump.rdb
最后,你还可以设置这个快照文件存放的路径。比如默认设置就是当前文件夹:
dir ./
3.复制:
主从复制(也叫主从同步)可以防止主机坏掉导致的网站不能正常运作的问题。Redis支持主从复制,而且配置也很简单。redis的主从复制可以让多个从服务器(slave server)拥有和主服务器(master server)相同的数据库副本。
特点:
1.一个master可以拥有多个slave
2.多个slave除了可以连接同一个master外,还可以连接其他的slave
3.不会阻塞master,在slave同步数据时,master可以继续处理客户端的请求
4.提高了系统的伸缩性,比如多个slave专门用于客户端的读操作
5.可在master服务器上禁止数据持久化,而只在slave服务器上进行数据持久化操作
Redis主从复制的过程,分为两个阶段,第一个阶段如下:
(1)slave服务器主动连接到master服务器。
(2)slave服务器发送SYNC命令到master服务器请求同步数据。
(3)master服务器备份数据库到rdb文件。
(4)master服务器将该rdb文件传输给slave服务器。
(5)slave服务器清空数据库数据,把rdb文件数据导入数据库中。
完成第一阶段,接下来master服务器把用户所有更改数据的操作(写操作),通过命令的形式转发给slave服务器,slave服务器只需执行master服务器发送过来的命令就可以实现后续的同步效果。Redis的主从复制配置很简单,只需在slave服务器的配置文件中,添加下面的配置项:
指定master(主服务器)的ip和端口
slaveof 192.168.1.115 6379
如果主服务器设置了安全密码,还要加上这行代码进行授权
masterauth 密码
当从redis失去了与主redis的连接,或者主从同步正在进行中时,redis该如何处理外部发来的访问请求呢?这里,从redis可以有两种选择,第一种选择:如果slave-serve-stale-data设置为yes(默认),则从redis仍会继续响应客户端的读写请求。第二种选择:如果slave-serve-stale-data设置为no,则从redis会对客户端的请求返回“SYNC with master in progress”,当然也有例外,当客户端发来INFO请求和SLAVEOF请求,从redis还是会进行处理。设置从redis只读:
slave-read-only yes
配置完成后,重启redis从服务器,就已经通过主从复制实现了数据的同步。
4.安全:
我们可以要求redis客户端在向redis-server发送请求之前,先进行密码验证。由于redis性能非常高,所以每秒钟可以完成多达15万次的密码尝试,所以你最好设置一个足够复杂的密码,否则很容易被黑客破解,我们设置一个密码(芝麻开门)。
requirepass zhimakaimen
redis允许我们对redis指令进行更名,比如将一些比较危险的命令改个名字,避免被误执行。比如可以把CONFIG命令改成一个很复杂的名字,这样可以避免外部的调用,同时还可以满足内部调用的需要:
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c89
我们甚至可以禁用掉CONFIG命令,那就是把CONFIG的名字改成一个空字符串:
rename-command CONFIG ""
需要注意的是,如果你使用AOF方式进行数据持久化,或者需要与从redis进行通信,那么更改指令的名字可能会引起一些问题。
5.限制:
我们可以设置redis同时可以与多少个客户端进行连接。默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。
maxclients 10000
我们甚至可以设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果redis无法根据移除规则来移除内存中的数据,或者我们设置了“不允许移除”,那么redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。但是对于无内存申请的指令,仍然会正常响应,比如GET等。默认设置为:
maxmemory <bytes>
需要注意的一点是,如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素。
对于内存移除规则来说,redis提供了多达6种的移除规则。他们是:
1.volatile-lru:使用LRU算法移除过期集合中的key
2.allkeys-lru:使用LRU算法移除key
3.volatile-random:在过期集合中移除随机的key
4.allkeys-random:移除随机的key
5.volatile-ttl:移除那些TTL值最小的key,即那些最近才过期的key。
6.noeviction:不进行移除。针对写操作,只是返回错误信息。
maxmemory-policy volatile-lru
LRU算法和最小TTL算法都并非是精确的算法,而是估算值。所以你可以设置样本的大小。假如redis默认会检查三个key并选择其中LRU的那个,那么你可以改变这个key样本的数量。
maxmemory-samples 3
6.追加模式--aof(redis持久化方法之二):
启用aof持久化方式
appendonly yes
日志追加(aof)方式比快照方式有更好的持久化性,如果启用了aof,Redis会将每一个收到的写命令通过write函数追加到文件appendonly.aof中,当Redis重启时,它会执行该文件中的所有命令,这样就可以在内存中重建整个redis数据库的内容。另外,操作系统内核的 I/O 接口可能存在缓存,所以日志追加方式不可能立即写入文件,这样就有可能丢失部分数据。幸运的是,Redis提供了解决方法,通过修改配置文件,告诉Redis应该在什么时候使用fsync函数强制操作系统把缓存中的写命令写入磁盘中的日志文件。有以下三种方法:
#appendfsync no 是否写入磁盘完全依赖操作系统,性能最好,持久化没保证
#appendfsync always 在每次写请求后都调用fsync()。这种模式下,redis会相对较慢,但数据最安全。
appendfsync everysec 每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中,最多存在一秒钟的数据丢失情况
默认情况下为everysec
当fsync方式设置为always或everysec时,如果后台持久化进程需要执行一个很大的磁盘IO操作,那么redis可能会在fsync()调用时卡住。目前尚未修复这个问题,这是因为即使我们在另一个新的线程中去执行fsync(),也会阻塞住同步写调用。为了缓解这个问题,我们可以使用下面的配置项,这样的话,当BGSAVE或BGWRITEAOF运行时,fsync()在主进程中的调用会被阻止。这意味着当另一路进程正在对AOF文件进行重构时,redis的持久化功能就失效了,就好像我们设置了“appendsync none”一样。如果你的redis有时延问题,那么请将下面的选项设置为yes。否则请保持no,因为这是保证数据完整性的最安全的选择。
no-appendfsync-on-rewrite no
我们允许redis自动重写aof。当aof增长到一定规模时,redis会隐式调用BGREWRITEAOF来重写log文件,以缩减文件体积。redis是这样工作的:redis会记录上次重写时的aof大小。假如redis自启动至今还没有进行过重写,那么启动时aof文件的大小会被作为基准值。这个基准值会和当前的aof大小进行比较。如果当前aof大小超出所设置的增长比例,则会触发重写。另外,你还需要设置一个最小大小,是为了防止在aof很小时就触发重写。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
如果设置auto-aof-rewrite-percentage为0,则会关闭此重写功能。
8.慢日志:
redis慢日志是指一个系统进行日志查询超过了指定的时长。这个时长不包括IO操作,比如与客户端的交互、发送响应内容等,而仅包括实际执行查询命令的时间。针对慢日志,你可以设置两个参数,一个是执行时长,单位是微秒,另一个是慢日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。单位是微秒,即1000000表示一秒。负数则会禁用慢日志功能,而0则表示强制记录每一个命令。
slowlog-log-slower-than 10000
慢日志最大长度,可以随便填写数值,没有上限,但要注意它会消耗内存。你可以使用SLOWLOG RESET来重设这个值。
slowlog-max-len 128