一,Redis 简介
redis 是一个基于内存的高性能 key-value 数据库,和 memcache 很像,但是其功能比 memcache 更强大,它可以持久化存储数据,单数整个数据库都是在内存当中进行操作的,所以其性能非常棒,支持超过每秒 10W 的读写速率,自己可以通过异步或同步操作把数据库数据 save 到硬盘上。redis 也支持多种数据结构,像 strings, hashes, lists, sets, sorted sets,redis的所有操作都是原子性的,此外,redis还支持发布订阅等高级特性。目前,Redis 3.0.7 is the latest stable version。
应用场景:新浪微博目前使用的是 redis, 用于评论,转发,阅读,点赞等的计数。
二,Redis 安装
Redis 的官网是 http://redis.io/,可以在官网下载最新版的 Redis ,以下所有试验使用的 3.0.5 版本。
# tar xf redis-3.0.5.tar.gz -C /usr/local/ # ln -s redis-3.0.5/ redis # cd redis # make && make install # cd src/ # ./redis-server & # 启动redis ,redis默认使用 6379 端口
[root@localhost redis]# redis-server & #首次启动redis时会出现以下错误 ......<code> 108239:M 01 May 04:43:53.631 # 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. </code> ...... [root@localhost redis]# sysctl vm.overcommit_memory=1 #使用此设置可以确保当 redis 使用的内存达到配置文件中指定的内存时,可以继续使用物理内存 vm.overcommit_memory = 1
vm.overcommit_memory 参数说明:
默认值为 0;
根据内核文档,该参数有三个值,分别是:
0:当用户空间请求更多的内存时,内核尝试估算剩余可用的内存。
1:当设置为 1 时,内核允许超量使用内存知道用完为止,主要用于科学计算。
2:当设置为 2 时,内核会使用一个绝不过量使用内存的算法,即系统整个地址空间不能超过 swap + 50% 的RAM值,50% 参数的设定是在 vm.overcommit_ratio 中设定的。
[root@localhost redis]# echo "vm.overcommit_memory=1" >> /etc/sysctl.conf [root@localhost redis]# sysctl -p # redis-cli 127.0.0.1:6379> ping PONG # ./redis-cli shutdown #关闭redis
三,Redis 配置文件详解
[root@cacti redis]# cat redis.conf | grep -v '#' | sed '/^$/d' ############################### GENERAL ##################################### daemonize no #默认情况下redis 不是以守护进程的模式运行 pidfile /var/run/redis.pid port 6379 #默认端口 tcp-backlog 511 timeout 0 #当客户端闲置多长时间后关闭连接,如果指定为0,表示不主动断开 tcp-keepalive 0 #长连接保持时间 loglevel notice #日志级别 logfile "" #指定日志文件路径 databases 16 #设定数据库的数量 ################################ SNAPSHOTTING ################################ #RDB快照部分:(将内存中的数据刷写到磁盘上) save 900 1 save 300 10 save 60 10000 # 符合以上条件的就刷新磁盘上: 900秒(15分钟)之后,且至少1次变更 300秒(5分钟)之后,且至少10次变更 60秒之后,且至少10000次变更 #阻塞客户端请求 高并发场景不要用 stop-writes-on-bgsave-error yes #默认情况下,如果在RDB snapshots持久化过程中出现问题,设置该参数后,Redis是不允许用户进行任何更新操作 rdbcompression yes #在导出.RDB数据库文件的时候采用LZF压缩字符串和对象。想节省一些CPU资源可以设置为no,但数据量可能会很大。 rdbchecksum yes #RDB快照制作过程中会在文件的末尾写入 crc64的校验值。这样可能很好的保证数据的正确性。 代价是在 saving 或者 loading RDB file 的时候,性能下降10%(待测试);如果仅用该选项的话, 文件末尾的校验值会用0代替,这样在loading data 的时候,会跳过check。 dbfilename dump.rdb #快照文件名 dir ./ #快照路径 ################################# REPLICATION ################################# #主从配置相关的 slaveof <masterip> <masterport> #只在slave添加该参数,用于创建从服务; masterauth <master-password> #如果master使用了requirepass参数,slave就要使用上述参数,进行密码验证。 slave-serve-stale-data yes #当slave丢失与master端的连接,或者复制仍在处理,那么slave会有下列两种表现: 当本参数值为yes时,slave为继续响应客户端请求,尽管数据已不同步甚至没有数据(出现在初次同步的情况下); 当本参数值为no时,slave会返回"SYNC with master in progreee"的错误信息; slave-read-only yes #只读 repl-diskless-sync no repl-diskless-sync-delay 5 # repl-ping-slave-period 10 #slave根据指定的时间间隔向服务器发送ping请求,默认10s repl-disable-tcp-nodelay no #默认为no,当选择yes的时候, master会向slave发送少量的tcp packets,这样的一个负面影响 delay slave接受数据时间,40 milliseconds 的延迟,在 高流量或者 master slave之间中间节点数很多的情况下,建议变为 yes slave-priority 100 #当master服务挂了后,优先级越低的slave,越有可能成为master候选人 ################################## SECURITY ################################### #安全相关的 # requirepass foobared #是否设置密码,requirepass +密码 #rename-command CONFIG "" #重命名或禁用某些命令 # maxclients 10000 #客户端并发数量 # maxmemory <bytes> #内存限制,过期会删除key ------------------------------------------------------------------------------- 查看当前内存使用情况: # redis-cli info memory # Memory used_memory:1883736 #redis 数据占用的内存 used_memory_human:1.80M used_memory_rss:9863168 #redis占用的物理内存 used_memory_peak:1884680 #使用的物理内存峰值 used_memory_peak_human:1.80M used_memory_lua:36864 mem_fragmentation_ratio:5.24 mem_allocator:jemalloc-3.6.0 ------------------------------------------------------------------------------ 一旦内存使用达到上限,Redis会根据选定的回收策略删除key,如果因为删除策略问题Redis无法删除key,或者策略设置为 "noeviction",Redis 会回复需要更多内存的错误信息给命令 但是会继续合理响应只读命令,比如:GET。 # maxmemory-policy noeviction # 内存策略:如果达到内存限制了,Redis使用以下5个策略来删除过期的key: volatile-lru -> 根据LRU算法生成的过期时间来删除。 allkeys-lru -> 根据LRU算法删除任何key。 volatile-random -> 根据过期设置来随机删除key。 allkeys->random -> 无差别随机删。 volatile-ttl -> 根据最近过期时间来删除(辅以TTL) noeviction -> 谁也不删,直接在写操作时返回错误。 对所有策略来说,如果Redis找不到合适的可以删除的key都会在写操作时返回一个错误。 ############################## APPEND ONLY MODE ############################### #redis 内存中的数据默认是异步同步到磁盘上的,如果发生宕机断电等情况,会造成几分钟数据的丢失。 Append Only File 也是数据持久化的一种方式,可以提供更好的数据可靠性, 默认使用fsync() 刷写磁盘数据,发生断电,或者Redis出现内部错误的时候最多丢失1秒数据。 AOF and RDB 这两种持久化方式可以同时开启不会发生冲突,开始AOF模式的话,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件。 每次启动时Redis都会把这个文件的数据读入内存里。 appendonly no #是否记录持久化日志 appendfilename "appendonly.aof" #AOF 文件 appendfsync everysec #每秒写一次 fsync() 请求操作系统马上把数据写到磁盘上 Redis支持三种不同的模式: no:不要立刻刷,只有在操作系统需要刷的时候再刷。比较快。 always:每次写操作都立刻写入到aof文件。慢,但是最安全。 everysec:每秒写一次。折衷方案。 默认的 "everysec" 通常来说能在速度和数据安全性之间取得比较好的平衡。 no-appendfsync-on-rewrite no #如果有延迟的问题那就把这个设为 "yes",否则就保持 "no",这是保存持久数据的最安全的方式。 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb #AOF文件自动重写。 如果AOF日志文件大到指定百分比,Redis能够通过 BGREWRITEAOF 自动重写AOF日志文件。 工作原理:Redis记住上次重写时AOF日志的大小(或者重启后没有写操作的话,那就直接用此时的AOF文件), 基准尺寸和当前尺寸做比较。如果当前尺寸超过指定比例,就会触发重写操作。 你还需要指定被重写日志的最小尺寸,这样避免了达到约定百分比但尺寸仍然很小的情况还要重写。 指定百分比为0会禁用AOF自动重写特性。百分比只是相对于下面设定的64mb而言的。 aof-load-truncated yes # redis在启动的时候可以加载被截断的AOF文件,默认启用;否则可能启动失败 ################################ LUA SCRIPTING ############################### lua-time-limit 5000 #lua 脚本执行时间限制 ################################ REDIS CLUSTER ############################### #Redis慢查询日志可以记录超过指定时间的查询。运行时间不包括各种I/O时间。 例如:连接客户端,发送响应数据等。 slowlog-log-slower-than 10000 slowlog-max-len 128 #慢查询日志长度,这个长度没有限制,单位为微妙,只要有足够的内存就行可以通过 SLOWLOG RESET 来释放内存 ################################ LATENCY MONITOR ############################## #延迟监控 latency-monitor-threshold 0 notify-keyspace-events "" ############################### ADVANCED CONFIG ############################### #高级特性 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 #当有大量数据时,适合用哈希编码但需要更多的内存,元素数量上限不能超过给定限制。 list-max-ziplist-entries 512 list-max-ziplist-value 64 #与哈希相类似,list数据元素较少的情况下,可以用另一种方式来编码从而节省大量空间。 set-max-intset-entries 512 #set 编码形式为是64位无符号整型数字构成的字符串。该参数来限制这种情况下使用这种编码的最大上限的。 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 #和 hashes,lists 相似,为了节约空间 sorted sets 也使用特殊的编码方式。这种编码只适合长度和元素都符合上面限制的有序序列。 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes #当子进程重写AOF文件,以下选项开启时,AOF文件会每产生32M数据同步一次,这有利于避免写入磁盘延迟。
四, redis 用法简介
redis 中的许多用法都和 mysql 的相似,后面将会一一介绍。
1,基本用法
127.0.0.1:6379> set id 01 #设置key-value OK 127.0.0.1:6379> get id "01" 127.0.0.1:6379> del id (integer) 1 127.0.0.1:6379> get id (nil) 127.0.0.1:6379> exists id #判断key是否存在,0表示不存在 (integer) 0 127.0.0.1:6379> set user1 01 OK 127.0.0.1:6379> set user2 02 OK 127.0.0.1:6379> keys * #查看所有的key 1) "user2" 2) "user1"
redis中默认有15个库,每个库之间都是相互隔离的,相当于mysql中的库
127.0.0.1:6379> select 16 (error) ERR invalid DB index 127.0.0.1:6379> select 1 #选择数据库1 OK 127.0.0.1:6379[1]> set name 'feiyu' OK 127.0.0.1:6379[1]> keys * 1) "name" 127.0.0.1:6379[1]> select 0 OK 127.0.0.1:6379> keys * 1) "user2" 2) "user1" 127.0.0.1:6379> flushdb #清除当前库的数据 OK 127.0.0.1:6379> flushall #清除所有库的数据 OK [root@localhost ~]# redis-cli -h 192.168.1.224 -p 6379 set k v #非交互式的方式 OK [root@localhost ~]# redis-cli -h 192.168.1.224 -p 6379 get k "v"
2,为 redis 设置密码
修改配置文件:
396 # requirepass foobared 397 requirepass feiyu
然后重启 redis 才能生效:
[root@localhost redis]# redis-server /usr/local/redis/redis.conf & [root@localhost redis]# redis-cli 127.0.0.1:6379> get user1 #此时需要认证 (error) NOAUTH Authentication required. 127.0.0.1:6379> auth feiyu #auth +密码 进行认证 OK 127.0.0.1:6379> get user1 "01" 127.0.0.1:6379> [root@localhost redis]# redis-cli -a feiyu #未指定主机与端口则为默认的,非交互式登录 127.0.0.1:6379> get user1 "01"
3,设置过期时间
127.0.0.1:6379> set name feiyu OK 127.0.0.1:6379> ttl name (integer) -1 #-1表示永远不过期 127.0.0.1:6379> expire name 3 #设置过期时间,单位为秒 (integer) 1 [root@localhost redis_data]# date +%s -d "2016-04-30 04:56:20" #取得时间戳 127.0.0.1:6379> EXPIREAT name 1462017480 #设置时间戳 (integer) 1
4,使用模式匹配,keys 也可以指定匹配的模式
127.0.0.1:6379> set name1 feiyu1 OK 127.0.0.1:6379> set name2 feiyu2 OK 127.0.0.1:6379> keys * 1) "name2" 2) "name1" 127.0.0.1:6379> keys name* 1) "name2" 2) "name1" 127.0.0.1:6379> keys name[0-9] 1) "name2" 2) "name1"
5,redis 事物
127.0.0.1:6379> set name feiyu OK 127.0.0.1:6379> setnx name feiyu1 #存在值则不改 (integer) 0 127.0.0.1:6379> multi #启动一个事物 OK 127.0.0.1:6379> set name a QUEUED 127.0.0.1:6379> set name b QUEUED 127.0.0.1:6379> exec #执行,若中间存在错误语句,则全不执行 1) OK 2) OK
6,数据保存
127.0.0.1:6379> save #同步方式保存,会阻塞某些请求 OK 127.0.0.1:6379> bgsave #异步方式保存数据 Background saving started
此命令将数据会保存在 .rdb 文件中。
正常停止redis时,会自动进行save,使用kill杀死是数据会丢失。