一、Redis介绍
Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server(远程数据服务),该软件使用C语言编写,Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多,包括string、list、set、zset和hash。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作。在此基础上,Redis支持各种不同方式的排序。
Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,这些可以通过配置文件对其进行配置,正因为这样,Redis才能实现持久化。因为Redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。
Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据.
Redis从它的许多竞争继承来的三个主要特点:
1.Redis数据库完全在内存中,使用磁盘仅用于持久性。
2.相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
3.Redis可以将数据复制到任意数量的从服务器。
4、Redis能支持超过 100K+ 每秒的读写频率
5、单个value限制是1GB,memcached为1M数据
Redis优势
异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
二、Redis的安装
[root@localhost app]# ls redis-3.2.8.tar.gz [root@localhost app]# tar zxvf redis-3.2.8.tar.gz [root@localhost app]# cd redis-3.2.8 [root@localhost redis-3.2.8]# yum -y install gcc gcc-c++ [root@localhost redis-3.2.3]# make #make MALLOC=libc 如果在make的时候不指定内存管理方式,会报错的: zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录。 malloc是管理内存碎片的。 Hint: It's a good idea to run 'make test' ;) make[1]: Leaving directory `/app/redis-3.2.3/src' [root@localhost redis-3.2.3]#
在执行完make之后,在最后的程序中会输出(t's a good idea to run 'make test'),它建议我们执行make test进行测试,那么接下来我们就输入make test,检查测试,是否出现问题,如出现如图所示:则说明测试没有问题:
[root@localhost redis-3.2.3]# cd src/ [root@localhost src]# make test You need tcl 8.5 or newer in order to run the Redis test make: *** [test] Error 1 [root@localhost src]# cd /app/ [root@localhost app]# wget [root@localhost app]# tar zxvf tcl8.6.1-src.tar.gz [root@localhost app]# cd tcl8.6.1/unix/ [root@localhost unix]# ./configure [root@localhost unix]# make && make install [root@localhost unix]# cd /app/redis-3.2.3/ [root@localhost redis-3.2.3]# make clean [root@localhost redis-3.2.3]# make [root@localhost redis-3.2.3]# cd src/ [root@localhost src]# make test 215 seconds - integration/replication-3 212 seconds - integration/replication-4 98 seconds - unit/hyperloglog 151 seconds - unit/obuf-limits \o/ All tests passed without errors! Cleanup: may take some time... OK [root@localhost src]# make install #make PREFIX=/app/redis install 注意PREFIX大写 Hint: It's a good idea to run 'make test' ;) INSTALL install INSTALL install INSTALL install INSTALL install INSTALL install [root@localhost src]#
注意:这里很可能会在make test 这步出现以下错误:
错误一
!!! WARNING The following tests failed: *** [err]: Test replication partial resync: ok psync (diskless: yes, reconnect: 1) in tests/integration/replication-psync.tcl Expected condition '[s -1 sync_partial_ok] > 0' to be true ([s -1 sync_partial_ok] > 0) Cleanup: may take some time... OK make: *** [test] Error 1 [root@localhost src]#
有2个方法可以避免:
1、在解压目录中修改 tests/integration/replication-psync.tcl,把 after 100 改成 after 500,这个参数貌似是等待的毫秒数
[root@localhost redis-3.2.3]# vim tests/integration/replication-psync.tcl if ($reconnect) { for {set j 0} {$j < $duration*10} {incr j} { after 500 # catch {puts "MASTER [$master dbsize] keys, SLAVE [$slave dbsize] keys"} [root@localhost redis-3.2.3]#
2、用taskset来make test
taskset -c 1 make test
错误二
[exception]: Executing test client: NOREPLICAS Not enough good slaves to write.. NOREPLICAS Not enough good slaves to write. ...... Killing still running Redis server 63439 Killing still running Redis server 63486 Killing still running Redis server 63519 Killing still running Redis server 63546 Killing still running Redis server 63574 Killing still running Redis server 63591 I/O error reading reply ...... "createComplexDataset $r $ops" (procedure "bg_complex_data" line 4) invoked from within "bg_complex_data [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]" (file "tests/helpers/bg_complex_data.tcl" line 10) Killing still running Redis server 21198 make: *** [test] Error 1 [root@localhost src]# vim ../tests/integration/replication-2.tcl start_server {tags {"repl"}} { start_server {} { test {First server should have role slave after SLAVEOF} { r -1 slaveof [srv 0 host] [srv 0 port] after 10000 #修改成10000 s -1 role } {slave}
错误三
[err]: Slave should be able to synchronize with the master in tests/integration/replication-psync.tcl Replication not started.
这个错误我重新make test就可以了,只遇到过一次
三、redis的配置
启动:
[root@localhost src]# redis-server ../redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.3 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 35217 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 35217:M 29 Mar 11:30:21.454 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 35217:M 29 Mar 11:30:21.454 # Server started, Redis version 3.2.3 35217:M 29 Mar 11:30:21.454 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 35217:M 29 Mar 11:30:21.454 * The server is now ready to accept connections on port 6379 ^C35217:signal-handler (1490758240) Received SIGINT scheduling shutdown... 35217:M 29 Mar 11:30:40.180 # User requested shutdown... 35217:M 29 Mar 11:30:40.180 * Saving the final RDB snapshot before exiting. 35217:M 29 Mar 11:30:40.191 * DB saved on disk 35217:M 29 Mar 11:30:40.191 * Removing the pid file. 35217:M 29 Mar 11:30:40.191 # Redis is now ready to exit, bye bye... [root@localhost src]#
这里直接执行Redis-server 启动的Redis服务,是在前台直接运行的(效果如上图),也就是说,执行完该命令后,如果Lunix关闭当前会话,则Redis服务也随即关闭。正常情况下,启动Redis服务需要从后台启动,并且指定启动配置文件。
编辑conf文件,将daemonize属性改为yes(表明需要在后台运行)
[root@localhost src]# vim ../redis.conf daemonize yes [root@localhost src]# redis-server ../redis.conf [root@localhost src]# netstat -anotp|grep :6379 tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 35415/redis-server off (0.00/0/0) [root@localhost src]# redis-cli shutdown #停止redis服务 [root@localhost src]# netstat -anotp|grep :6379
配置
为了方便管理,将Redis文件中的conf配置文件和常用命令移动到统一文件中
[root@localhost app]# mkdir -p redis6379/{log,conf,data,bin} [root@localhost src]# cp redis-server redis-benchmark redis-cli mkreleasehdr.sh redis-check-aof /app/redis6379/bin/ [root@localhost src]# cp ../redis.conf /app/redis6379/conf/ [root@localhost src]# pwd /app/redis-3.2.3/src [root@localhost src]# cd /app/redis6379/bin/ [root@localhost bin]# redis-server ../conf/redis.conf [root@localhost bin]# netstat -antp|grep :6379 tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 36334/redis-server [root@localhost bin]# cp /etc/sysctl.conf{,.bak} [root@localhost bin]# vim /etc/sysctl.conf vm.overcommit_memory = 1 [root@localhost bin]# sysctl -p
redis-benchmark redis性能检测工具
测试Redis的读写性能:
[root@localhost bin]# ./redis-benchmark -h localhost -p 6979 -c 100 -n 100000 #100个并发连接,100000个请求 ...... ====== MSET (10 keys) ====== 100000 requests completed in 0.94 seconds #100000个请求完成于 0.94 秒 100 parallel clients #每个请求有100个并发客户端 3 bytes payload #每次写入3字节 keep alive: 1 #保持1个连接 99.92% <= 1 milliseconds 100.00% <= 1 milliseconds 106609.80 requests per second #每秒106609.80次查询
参数:
-h 设置检测主机IP地址,默认为127.0.0.1
-p 设置检测主机的端口号,默认为6379
-s<socket> 服务器套接字(压倒主机和端口)
-c 并发连接数
-n 请求数
-d 测试使用的数据集的大小/字节的值(默认3字节)
-k 1:表示保持连接(默认值)0:重新连接
-r SET/GET/INCR方法使用随机数插入数值,设置10则插入值为rand:000000000000 - rand:000000000009
-P 默认为1(无管道),当网络延迟过长时,使用管道方式通信(请求和响应打包发送接收)
-q 简约信息模式,只显示查询和秒值等基本信息。
--csv 以CSV格式输出信息
-l 无线循环插入测试数据,ctrl+c停止
-t<tests> 只运行<tests>测试逗号分隔的列表命令,如:-t ping,set,get
-I 空闲模式。立即打开50个空闲连接和等待。
redis-check-rdb 检查rbd日志的工具
redis-check-dump 检查本地数据库文件
redis-check-dump dump.rdb
redis-sentinel Redis集群的管理工具 监控多个master-slave集群,发现master宕机后能进行自动切换
redis-check-aof 检查aof日志的工具
redis-check-aof appendonly.aof
--fix参数为修复log文件
redis-cli Redis命令行操作工具
参数:
-h 设置检测主机IP地址,默认为127.0.0.1
-p 设置检测主机的端口号,默认为6379
-s<socket> 服务器套接字(压倒主机和端口)
-a 连接到Master服务器时使用的密码
-r 执行指定的N次命令,eg:redis-cli -r 3 info 重复执行info命令三次-i 执行命令后等待N秒,如–i 0.1 info(执行后等0.1秒),eg:redis-cli -r 100 -i 1 info | grep used_memory_human
-n 指定连接N号ID数据库,如 –n 3(连接3号数据库)
-x 从控制台输入的信息中读取最后一个参数,eg:cat testStr.txt | redis-cli -x set testStr读取testStr.txt文件所有内容设置为testStr的值-d 定义多个定界符为默认输出格式(默认: \n)
--raw 使用原数据格式返回输出内容
--latency 进入一个不断延时采样的特殊模式
--slave 模拟一个从服务器到主服务器的命令显示反馈
--pipe 使用管道协议模式
--bigkeys 监听显示数据量大的key值,--bigkeys -i 0.1
--help 显示命令行帮助信息
--version 显示版本号
[root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 info #查看info信息 [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 Warning: Using a password with '-a' option on the command line interface may not be safe. 10.15.97.136:6979> keys \* #查看所有键值信息 (empty list or set) 10.15.97.136:6979> [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 -n 15 #登陆15号数据库 [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 info|grep "\<used_memory\>" #过滤查询used_memory属性 Warning: Using a password with '-a' option on the command line interface may not be safe. used_memory:902799 [root@localhost bin]#
当used_memory_rss接近maxmemory或者used_memory_peak超过maxmemory时,要加大maxmemory 负责性能下降。
maxmemory:
不要用比设置的上限更多的内存。一旦内存使用达到上限,Redis会根据选定的回收策略(参见:maxmemmory-policy:内存策略设置)删除key。如果因为删除策略问题Redis无法删除key,或者策略设置为 "noeviction",Redis会回复需要更多内存的错误信息给命令。例如,SET,LPUSH等等。但是会继续合理响应只读命令,比如:GET。在使用Redis作为LRU缓存,或者为实例设置了硬性内存限制的时候(使用 "noeviction" 策略)的时候,这个选项还是满有用的。当一堆slave连上达到内存上限的实例的时候,响应slave需要的输出缓存所需内存不计算在使用内存当中。当请求一个删除掉的key的时候就不会触发网络问题/重新同步的事件,然后slave就会收到一堆删除指令,直到数据库空了为止。slave连上一个master的话,建议把master内存限制设小点儿,确保有足够的系统内存用作输出缓存。(如果策略设置为"noeviction"的话就不无所谓了),设置最大内存,达到最大内存设置后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,任到达最大内存设置,将无法再进行写入操作。
设置内存分配策略vm.overcommit_memory = 1 ;否则Redis脚本在重启或停止redis时,将会报错,并且不能自动在停止服务前同步数据到磁盘上
/proc/sys/vm/overcommit_memory可选值:0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
值得注意的一点是,redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)
redis服务关闭后,缓存数据会自动dump到硬盘上,硬盘地址为redis.conf中的配置项dbfilename dump.rdb所设定
redis配置文件简介
[root@localhost conf]# vim redis.conf # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # units are case insensitive so 1GB 1Gb 1gB are all the same. #当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其内存单位转换方式如下(不区分大小写,比如 1gb 1Gb 1GB 1gB均可) daemonize yes #是否以后台进程运行,默认为no pidfile /var/run/redis_6379.pid #如以后台进程运行,需指定一个pid路径,默认为/var/run/redis.pid port 6379 #监听端口,默认为6379 # unixsocket /tmp/redis.sock #指定用来监听连接的unxi套接字的路径。这个没有默认值,所以如果不指定的话,Redis就不会通过unix套接字来监听。 # unixsocketperm 700 timeout 300 #超时时间,当客户端在这段时间内没有发出任何指令,那么关闭该连接,默认为0(秒),永不超时 loglevel notice #日志记录等级,有4个可选值,debug适用于开发和测试,verbose更详细信息,notice适用于生产环境,warning只记录警告或错误信息 logfile /app/redis6379/log/redis.log #日志记录方式,默认值为stdout # syslog-enabled no #是否将日志输出到系统日志 # syslog-ident redis #设置linux系统日志syslog的标示符,若是"syslog-enabled=no",则这个选项无效。 # syslog-facility local0 #设置syslog的facility,必须是USER或者是 LOCAL0-LOCAL7之间的值。 slave-serve-stale-data yes #当slave与master之间的连接断开或slave正在与master进行数据同步时,如果有slave请求,当设置为yes时,slave仍然响应请求,此时可能有问题,如果设置no时,slave会返回"SYNC with master in progress"错误信息。但INFO和SLAVEOF命令除外。 databases 16 #可用数据库数,默认值为16, ############### 快照方式 ############### save 900 1 #900秒(15分钟)内至少有1个key被改变,则快照 save 300 10 #300秒(5分钟)内至少有10个key被改变 ,则快照 save 60 10000 #60秒内至少有10000个key被改变,则快照,如果不需要写磁盘,则把所有 "save" 设置注释掉 rdbcompression yes #存储至本地数据库时是否压缩数据,默认为yes,如果你希望保存子进程节省点 cpu ,你就设置它为 no ,不过这个数据集可能就会比较大 dbfilename dump.rdb #本地数据库文件名,默认值为dump.rdb rdbchecksum yes #是否校验rdb文件 dir /app/redis6379/data #本地数据库存放路径,默认值为 ./ 工作目录 tcp-keepalive 60 #tcp 心跳包,推荐一个合理的值就是60秒,防止死的 peers ############### 主从复制 ############### # slaveof <masterip> <masterport> #slaveof 10.0.0.12 6379 #当本机为从服务时,设置主服务的IP及端口 # masterauth <master-password> #masterauth justin #当master设置密码认证,slave用此选项指定master认证密码 # repl-ping-slave-period 10 #Slaves在一个预定义的时间间隔内发送ping命令到server, 默认为10秒。可以通过 repl_ping_slave_period 来设置 # repl-timeout 60 #设置主从复制大块数据I/O、向master请求数据和ping响应的过期时,这个值一定要比repl-ping-slave-period大,否则master和slave之间的传输过期时间比预想的要短。 # requirepass foobared # requirepass justin #设置redis密码 # maxclients 10000 #设置最大同时连接客户端数量,0为不限制,这个关系到Redis进程能够打开的文件描述符数量,一旦达到这个限制,Redis会关闭所有新连接并发送错误"达到最大用户数上限(max number of clients reached)" # maxmemory <bytes> #指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区 appendonly no #指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no # maxmemory-policy noeviction #如果达到maxmemory值,采用此策略,可以采取的动作,volatile-lru :默认策略,只对设置过期时间的key进行LRU算法删除,allkeys-lru :删除不经常使用的key,volatile-random :随机删除即将过期的key,allkeys-random :随机删除一个key,volatile-ttl :删除即将过期的key,noeviction :不过期,写操作返回报错。 # maxmemory-samples 5 #默认随机选择5个key,从中淘汰最不经常用的 appendfilename "appendonly.aof" #更新日志文件名,默认值为appendonly.aof appendfsync everysec #更新日志条件,共有3个可选值。no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次 no-appendfsync-on-rewrite no #日志文件即将增长到指定百分比时,redis通过调用BGREWRITEAOF是否自动重写AOF日志文件。 really-use-vm yes vm-enabled yes #是否使用虚拟内存,默认值为no,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中 vm-swap-file /tmp/redis.swap #虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享 vm-max-memory 0 #vm大小限制。0:不限制,建议60-80% 可用内存大小。将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0 vm-page-size 32 #根据缓存内容大小调整,默认32字节。Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值 vm-pages 134217728 #page数。每 8 page,会占用1字节内存。设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。 vm-page-size #vm-pages 等于 swap 文件大小 vm-max-threads 4 #vm 最大io线程数。注意: 0 标志禁止使用vm,设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4 include /path/to/local.conf #指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
maxmemory <bytes> 设置最大内存,maxmemory是bytes字节类型,注意转换,如果设置了maxmemory,一般都要设置过期策略,默认策略maxmemory-policy volatile-lru对设置过期时间的key进行LRU(Least Recently Used 近期最少使用算法)算法删除,如果set时候没有加上过期时间就会导致数据写满maxmemory,此时将无法再进行写入操作。
volatile-lru -> 根据LRU算法生成的过期时间来删除。
allkeys-lru -> 根据LRU算法删除任何key。
volatile-random -> 根据过期设置来随机删除key。
allkeys->random -> 无差别随机删。
volatile-ttl -> 根据最近过期时间来删除(辅以TTL)
noeviction -> 谁也不删,直接在写操作时返回错误。
maxmemory 16777216 #设置最大内存16GB,一般推荐Redis设置内存为最大物理内存的四分之三。
Redis使用超过设置的最大值,在debug模式下的页面,提示错误:OOM command not allowed when used memory > ‘maxmemory’.
redis的持久化方式分两种
1.rdb模式
其实就是对内存中的东西按一些策略定期做snapshot,也就是快照,rdb保存的是二进制文件,是redis的默认方式。
save <seconds> <changes> #100秒内至少有10个key值发生改变才做持久化 save 100 10 #最新的快照保存失败时停止写操作 stop-writes-on-bgsave-error yes #做快照时是不是需要做压缩 rdbcompression yes #数据校验,保证数据正确性 rdbchecksum yes #快照的文件名 dbfilename dump.rdb #存放快照的目录 dir /var/lib/redis
2.Append only file(AOF)的方式
它将每一步操作的命令强制保存到磁盘上,持久性比较好,但对于写比较频繁的情况不适合,不推荐。 配置如下:
appendonly no #append only file的名称,默认为appendonly.aof appendfilename "appendonly.aof" #在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK IO上的冲突。 no-appendfsync-on-rewrite yes
强制同步数据到磁盘: redis-cli save 或 redis-cli -p 6380 save (根据端口号指定某台服务器同步)
info命令查看Redis内存使用情况
[root@localhost redis6379]# cd bin/ [root@localhost bin]# ./redis-cli 127.0.0.1:6379> info # Server redis_version:3.2.3 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:9f41557dffea5d14 redis_mode:standalone os:Linux 2.6.32-642.el6.x86_64 x86_64 arch_bits:64 #64位系统 multiplexing_api:epoll # Redis 所使用的事件处理机制 gcc_version:4.4.7 process_id:1381 #当前服务器进程id run_id:94e9454ecd837dc2b3fc6e41499ecc058679daae #Redis 服务器的随机标识符(用于 Sentinel 和集群) tcp_port:6379 uptime_in_seconds:723584 #正常工作时间(秒) uptime_in_days:8 #正常工作天数 hz:10 lru_clock:16736529 executable:/app/redis6379/bin/redis-server config_file:/app/redis6379/conf/redis.conf # Clients connected_clients:1 #客户端连接数 connected_slaves:0 #从服务器连接数 client_longest_output_list:0 #当前连接的客户端当中,最长的输出列表 client_biggest_input_buf:0 #当前连接的客户端当中,最大输入缓存 blocked_clients:0 #正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量 # Memory used_memory:289912 #由Redis分配器分配的内存总量(edis数据占用的内存),以字节(byte)为单位 used_memory_human:283.12K #以人类可读的格式返回Redis分配的内存总量,重点关注 used_memory_rss:1196032 #从操作系统的角度,返回Redis已分配的内存总量(redis占用的物理内存)。这个值和top、ps等命令的输出一致。 used_memory_rss_human:1.14M used_memory_peak:289912 #redis使用物理内存的峰值(以字节为单位) used_memory_peak_human:283.12K total_system_memory:505806848 total_system_memory_human:482.38M used_memory_lua:37888 # Lua 引擎所使用的内存大小(以字节为单位) used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:4.13 #内存碎片率,used_memory_rss和used_memory之间的比率 mem_allocator:jemalloc-4.0.3 #内存分配器版本,在编译时指定的Redis所使用的内存分配器。可以是libc、jemalloc或者tcmalloc。 #在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。 #当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。 #当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。查看 used_memory_peak 的值可以验证这种情况是否发生。 # Persistence RDB 和 AOF 的相关信息 loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 #后台异步保存数据的进程数 rdb_last_save_time:1492407953 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 aof_enabled:1 #是否开启纯累加模式 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_current_size:0 aof_base_size:0 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0 # Stats 一般统计信息 total_connections_received:1 #接受到的总连接数 total_commands_processed:1 #服务器处理的命令数量 instantaneous_ops_per_sec:0 total_net_input_bytes:31 total_net_output_bytes:5935693 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 #失效key的总数量 evicted_keys:0 #已删除的key的总数量 keyspace_hits:0 #Key命中次数 keyspace_misses:0 #Key未命中次数 pubsub_channels:0 #订阅信息 pubsub_patterns:0 latest_fork_usec:0 #最近子进程 migrate_cached_sockets:0 # Replication 主/从复制信息 role:master #master为主服务器slave为从服务器 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:386.43 #Cpu使用率 used_cpu_user:218.25 used_cpu_sys_children:0.00 used_cpu_user_children:0.00 #commandstats Redis 命令统计信息 # Cluster Redis 集群信息 cluster_enabled:0 # Keyspace 数据库相关的统计信息 db0:keys=2,expires=0,avg_ttl=0 #1号数据库保存的key数量,及超时时间 127.0.0.1:6379>
将Redis配置成服务
[root@localhost conf]# cp /usr/local/redis-3.2.8/utils/redis_init_script /etc/rc.d/init.d/redis [root@localhost conf]# cat /etc/rc.d/init.d/redis #!/bin/bash #chkconfig: 2345 10 90 #description: Redis server is an open source, advanced key-value store. # source function library source /etc/rc.d/init.d/functions port="6379" pidfile="/var/run/redis_$port.pid" lockfile="/var/lock/subsys/redis-server" rootpath="/app/redis$port" config="$rootpath/conf/redis.conf" binpath="$rootpath/bin" [ -r "$SYSCONFIG" ] && source "$SYSCONFIG" reids_status(){ status -p $pidfile redis-server } start() { if [ -e $pidfile ];then echo "Redis Server aleady running......" exit 1 else echo -n "Starting Redis Server......" $binpath/redis-server $config value=$? [ $value -eq 0 ] && touch $lockfile && echo "OK" return $value fi } stop() { echo -n "Stop Redis Server......" killproc redis-server # $binpath/redis-cli save && $binpath/redis-cli shutdown value=$? [ $value -eq 0 ] && rm -rf $lockfile $pidfile return $value } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) reids_status ;; *) echo $"Usage: $0 {start|stop|restart|status}" esac [root@localhost conf]# chkconfig --add redis [root@localhost conf]# chkconfig --level 2345 redis on [root@localhost conf]# chmod +x /etc/rc.d/init.d/redis
三、redis的测试
[root@localhost src]# redis-cli #redis-cli -h host -p port -a password 127.0.0.1:6379> set justin "WeChat ID:ityunwei2017" #向redis中插入键值对数据,键为justin,值为WeChat ID:ityunwei2017 OK 127.0.0.1:6379> get justin #根据键取值 "WeChat ID:ityunwei2017" 127.0.0.1:6379> exists justin #查看键是否存在 (integer) 1 127.0.0.1:6379> exists justin1 (integer) 0 127.0.0.1:6379> del justin #删除当前key (integer) 1 127.0.0.1:6379> exists justin (integer) 0 127.0.0.1:6379> keys * #查看所有键 127.0.0.1:6379> dbsize #键总数 127.0.0.1:6379> 127.0.0.1:6379> quit [root@localhost src]# redis-benchmark -h 127.0.0.1 -p 6379 -n 10 -c 50
redis-benchmark -h 127.0.0.1 -p 6379 -n 10 -c 50 向redis服务器发送10个请求,每个请求附带50个并发客户端,-n 接请求数,-c 接并发数
Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西。所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响。Redis在编译时,会先判断是否使用tcmalloc,如果是,会用tcmalloc对应的函数替换掉标准的libc中的函数实现。其次会判断jemalloc是否使得,最后如果都没有使用才会用标准的libc中的内存管理函数。
从最新的版本中,jemalloc已经作为源码包的一部分包含在源码包中,所以可以直接被使用。而如果你要使用tcmalloc的话,是需要自己安装的。
与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
tcmalloc(Thread-Caching Malloc)是google-proftools( http://code.google.com/p/gperftools/downloads/list)中的一部分,所以我们实际上需要安装google-proftools。64位操作系统需先安装libunwind库(32位操作系统不要安装)
libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
编译环境
[root@justin ~]# yum -y install gcc gcc+ gcc-c++ openssl openssl-devel pcre pcre-devel
安装tcmalloc包
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
安装google-preftools包
wget http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz
tar zxvf google-perftools-1.8.1.tar.gz
cd google-perftools-1.8.1/
./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --disable-debugalloc --enable-minimal
make && make install
sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf #如果没有这个文件,自己建一个
sudo /sbin/ldconfig
cd /usr/local/lib
ln -sv libtcmalloc_minimal.so.4.1.2 libtcmalloc.so
安装Redis包
cd redis-4.11
make PREFIX=/opt/redis USE_TCMALLOC=yes FORCE_LIBC_MALLOC=yes
make install
对于tcmalloc,jemalloc和libc对应的三个内存分配器。其性能和碎片率如何,可以使用Redis自带的redis-benchmark写入等量数据进行测试
1、测试数据都是小数据,也就是说单条数据并不大时,采用tcmalloc时碎片率是最低的,为1.01,jemalloc为1.02,而libc的分配器碎片率为1.31
2、设置benchmark的-d参数,将value值调整为1k大小,采用tcmalloc时碎片率是最低的,为1.02,jemalloc为1.01,而libc的分配器碎片率为1.04
四、Redis配置多实例
多实例比较简单,通过不通配置文件就可以生成不通的实例,这里我们生成100歌实例为例
先将默认的配置文件配置好,例如端口、日志名称、数据文件名等改成带有端口号表示的(根据自己的爱好来定义)
[root@localhost ~]# vim /app/redis/etc/redis.conf ... port 6979 pidfile /var/run/redis_6979.pid logfile /app/redis/logs/redis_6979.log dbfilename 6979.rdb ... [root@localhost ~]# for n in `seq 8000 8099`;do cp redis.conf redis$n.conf && sed -i "s/6379/$n/g" redis$n.conf;done [root@localhost ~]# for n in `seq 8000 8099`;do /app/redis/bin/redis-server /app/redis/etc/redis$n.conf;done
五、Redis主从配置
Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构。
1、redis主不需要特别配置,按照正常配置即可
2、redis从,需要在配置文件里指定redis主
我这里在一台主机上配置多实例做为主从
[root@localhost etc]# vim redis6380.conf # slaveof <masterip> <masterport> slaveof 127.0.0.1 6379 # masterauth <master-password> 如果master设置了验证密码,还需配置masterauth masterauth justin
启动master、slave的redis执行info命令查看结果:
master
[root@localhost etc]# ../bin/redis-cli -h 127.0.0.1 -p 6379 -a justin 127.0.0.1:6379> info # Replication role:master #主 connected_slaves:3 #3个从连接信息 slave0:ip=127.0.0.1,port=6380,state=online,offset=2314790043,lag=1 slave1:ip=127.0.0.1,port=6381,state=online,offset=2314790043,lag=1 slave2:ip=127.0.0.1,port=6382,state=online,offset=2314790043,lag=1 master_replid:10f3abe30f7ff3991dd6a15ccccd4ebdce1bb35a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2314790043 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2313741468 repl_backlog_histlen:1048576
slave
[root@localhost etc]# ../bin/redis-cli -p 6380 127.0.0.1:6380> info # Replication role:slave #从 master_host:127.0.0.1 master_port:6379 master_link_status:up #状态为UP说明和主连接上了,否则为down master_last_io_seconds_ago:1 #距离最后一次的连接时间 master_sync_in_progress:0 #同步主服务器进程数 slave_repl_offset:2320002171 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:10f3abe30f7ff3991dd6a15ccccd4ebdce1bb35a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2320002171 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2318953596 repl_backlog_histlen:1048576
此时在master里set个值,在slave里get就可以得到该值说明配置成功
slave:6380 master:6379
[root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * (empty list or set) 127.0.0.1:6380> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set justin 51cto OK 127.0.0.1:6379> get justin "51cto" 127.0.0.1:6379> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> keys * 1) "justin" 127.0.0.1:6379> quit [root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * 1) "justin" 127.0.0.1:6380> set justin1 51cto #Slave不可以写,只可以读 (error) READONLY You can't write against a read only slave. 127.0.0.1:6380> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> del justin (integer) 1 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> exit [root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * (empty list or set) 127.0.0.1:6380>
六、最大缓存设置
示例:maxmemory 100mb
单位:mb,gb。
默认不限制,如果有新的数据添加,超过最大内存,则会使redis崩溃,设置最好为物理内存的3/4,或者比例更小,因为redis复制数据等其他服务时,也是需要缓存的。以防缓存数据过大致使redis崩溃,造成系统出错不可用。设置maxmemory之后,配合的要设置缓存数据回收策略。
当maxmemory限制到达的时候,Redis将采取的准确行为是由maxmemory-policy配置指令配置的。
(1)、noeviction:当到达内存限制时返回错误。当客户端尝试执行命令时会导致更多内存占用(大多数写命令,除了DEL和一些例外)。
(2)、allkeys-lru:回收最近最少使用(LRU)的键,为新数据腾出空间。
(3)、volatile-lru:回收最近最少使用(LRU)的键,但是只回收有设置过期的键,为新数据腾出空间。
(4)、allkeys-random:回收随机的键,为新数据腾出空间。
(5)、volatile-random:回收随机的键,但是只回收有设置过期的键,为新数据腾出空间。
(6)、volatile-ttl:回收有设置过期的键,尝试先回收离TTL最短时间的键,为新数据腾出空间。
如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru,如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random。
redis启动时日志的几个报警错误
1、The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128
TCP backlog设置值,511没有成功,因为 /proc/sys/net/core/somaxconn这个设置的是更小的128;baklog参数实际控制的是已经3次握手成功的还在accept queue的大小。
echo 511 > /proc/sys/net/core/somaxconn (将其写入/etc/rc.local文件中)
2、overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
overcommit_memory参数设置为0!在内存不足的情况下,后台程序save可能失败。建议在文件 /etc/sysctl.conf 中将overcommit_memory修改为1。
echo "vm.overcommit_memory=1" > /etc/sysctl.conf
3、you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix thisissue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain thesetting after a reboot. Redis must be restarted after THP is disabled.
使用的是透明大页,可能导致redis延迟和内存使用问题。执行 echo never > /sys/kernel/mm/transparent_hugepage/enabled 修复该问题。
echo never > /sys/kernel/mm/transparent_hugepage/enabled (将其写入/etc/rc.local文件中)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。