Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
Redis 键命令用于管理 redis 的键。
语法
Redis 键命令的基本语法如下:
- redis 127.0.0.1 : 6379 > COMMAND KEY_NAME
实例
- redis 127.0.0.1:6379> SET runoobkey redis
- OK
- redis 127.0.0.1:6379> DEL runoobkey
- (integer) 1
在以上实例中 DEL 是一个命令, runoobkey 是一个键。 如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0
- 1 DEL key
- 该命令用于在 key 存在时删除 key。
- 2 DUMP key
- 序列化给定 key ,并返回被序列化的值。
- 3 EXISTS key
- 检查给定 key 是否存在。
- 4 EXPIRE key seconds
- 为给定 key 设置过期时间。
- 5 EXPIREAT key timestamp
- EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
- 6 PEXPIRE key milliseconds
- 设置 key 的过期时间以毫秒计。
- 7 PEXPIREAT key milliseconds-timestamp
- 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
- 8 KEYS pattern
- 查找所有符合给定模式( pattern)的 key 。
- 9 MOVE key db
- 将当前数据库的 key 移动到给定的数据库 db 当中。
- 10 PERSIST key
- 移除 key 的过期时间,key 将持久保持。
- 11 PTTL key
- 以毫秒为单位返回 key 的剩余的过期时间。
- 12 TTL key
- 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
- 13 RANDOMKEY
- 从当前数据库中随机返回一个 key 。
- 14 RENAME key newkey
- 修改 key 的名称
- 15 RENAMENX key newkey
- 仅当 newkey 不存在时,将 key 改名为 newkey 。
- 16 TYPE key
- 返回 key 所储存的值的类型。
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个键最大能存储512MB。
实例
- redis 127.0.0.1:6379> SET name "runoob"
- OK
- redis 127.0.0.1:6379> GET name
- "runoob"
在以上实例中我们使用了 Redis 的 SET 和 GET 命令。键为 name,对应的值为 runoob。
注意:一个键最大能存储512MB。
Redis hash 是一个键名对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
实例
- 127.0.0.1:6379> HMSET user:1 username runoob password runoob points 200
- OK
- 127.0.0.1:6379> HGETALL user:1
- 1) "username"
- 2) "runoob"
- 3) "password"
- 4) "runoob"
- 5) "points"
- 6) "200"
以上实例中 hash 数据类型存储了包含用户脚本信息的用户对象。 实例中我们使用了 Redis HMSET, HGETALL 命令,user:1为键值。
每个 hash 可以存储 232 -1 键值对(40多亿)。
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
实例
- redis 127.0.0.1:6379> lpush runoob redis
- (integer) 1
- redis 127.0.0.1:6379> lpush runoob mongodb
- (integer) 2
- redis 127.0.0.1:6379> lpush runoob rabitmq
- (integer) 3
- redis 127.0.0.1:6379> lrange runoob 0 10
- 1) "rabitmq"
- 2) "mongodb"
- 3) "redis"
- redis 127.0.0.1:6379>
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
sadd 命令
添加一个string元素到,key对应的set集合中,成功返回1,如果元素已经在集合中返回0,key对应的set不存在返回错误。
- sadd key member
实例
- redis 127.0.0.1:6379> sadd runoob redis
- (integer) 1
- redis 127.0.0.1:6379> sadd runoob mongodb
- (integer) 1
- redis 127.0.0.1:6379> sadd runoob rabitmq
- (integer) 1
- redis 127.0.0.1:6379> sadd runoob rabitmq
- (integer) 0
- redis 127.0.0.1:6379> smembers runoob
- 1) "rabitmq"
- 2) "mongodb"
- 3) "redis"
注意:以上实例中 rabitmq 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。
集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
zadd 命令
添加元素到集合,元素在集合中存在则更新对应score
- zadd key score member
实例
- redis 127.0.0.1:6379> zadd runoob 0 redis
- (integer) 1
- redis 127.0.0.1:6379> zadd runoob 0 mongodb
- (integer) 1
- redis 127.0.0.1:6379> zadd runoob 0 rabitmq
- (integer) 1
- redis 127.0.0.1:6379> zadd runoob 0 rabitmq
- (integer) 0
- redis 127.0.0.1:6379> ZRANGEBYSCORE runoob 0 1000
- 1) "redis"
- 2) "mongodb"
- 3) "rabitmq"
Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf。
你可以通过 CONFIG 命令查看或设置配置项。
语法
Redis CONFIG 命令格式如下:
- redis 127.0.0.1 : 6379 > CONFIG GET CONFIG_SETTING_NAME
实例
- redis 127.0.0.1:6379> CONFIG GET loglevel
- 1) "loglevel"
- 2) "notice"
使用 * 号获取所有配置项:
实例
- is 127.0.0.1:6379> CONFIG GET *
- ) "dbfilename"
- ) "dump.rdb"
- ) "requirepass"
- ) ""
- ) "masterauth"
- ) ""
- ) "unixsocket"
- ) ""
- ) "logfile"
- ) ""
- ) "pidfile"
- ) "/var/run/redis.pid"
- ) "maxmemory"
- ) "0"
- ) "maxmemory-samples"
- ) "3"
- ) "timeout"
- ) "0"
- ) "tcp-keepalive"
- ) "0"
- ) "auto-aof-rewrite-percentage"
- ) "100"
- ) "auto-aof-rewrite-min-size"
- ) "67108864"
- ) "hash-max-ziplist-entries"
- ) "512"
- ) "hash-max-ziplist-value"
- ) "64"
- ) "list-max-ziplist-entries"
- ) "512"
- ) "list-max-ziplist-value"
- ) "64"
- ) "set-max-intset-entries"
- ) "512"
- ) "zset-max-ziplist-entries"
- ) "128"
- ) "zset-max-ziplist-value"
- ) "64"
- ) "hll-sparse-max-bytes"
- ) "3000"
- ) "lua-time-limit"
- ) "5000"
- ) "slowlog-log-slower-than"
- ) "10000"
- ) "latency-monitor-threshold"
- ) "0"
- ) "slowlog-max-len"
- ) "128"
- ) "port"
- ) "6379"
- ) "tcp-backlog"
- ) "511"
- ) "databases"
- ) "16"
- ) "repl-ping-slave-period"
- ) "10"
- ) "repl-timeout"
- ) "60"
- ) "repl-backlog-size"
- ) "1048576"
- ) "repl-backlog-ttl"
- ) "3600"
- ) "maxclients"
- ) "4064"
- ) "watchdog-period"
- ) "0"
- ) "slave-priority"
- ) "100"
- ) "min-slaves-to-write"
- ) "0"
- ) "min-slaves-max-lag"
- ) "10"
- ) "hz"
- ) "10"
- ) "no-appendfsync-on-rewrite"
- ) "no"
- ) "slave-serve-stale-data"
- ) "yes"
- ) "slave-read-only"
- ) "yes"
- ) "stop-writes-on-bgsave-error"
- ) "yes"
- ) "daemonize"
- ) "no"
- ) "rdbcompression"
- ) "yes"
- ) "rdbchecksum"
- ) "yes"
- ) "activerehashing"
- ) "yes"
- ) "repl-disable-tcp-nodelay"
- ) "no"
- ) "aof-rewrite-incremental-fsync"
- ) "yes"
- ) "appendonly"
- ) "no"
- ) "dir"
- ) "/home/deepak/Downloads/redis-2.8.13/src"
- ) "maxmemory-policy"
- ) "volatile-lru"
- ) "appendfsync"
- ) "everysec"
- ) "save"
- ) "3600 1 300 100 60 10000"
- ) "loglevel"
- ) "notice"
- ) "client-output-buffer-limit"
- ) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
- ) "unixsocketperm"
- ) "0"
- ) "slaveof"
- ) ""
- ) "notify-keyspace-events"
- ) ""
- ) "bind"
- ) ""
你可以通过修改 redis.conf 文件或使用 CONFIG set 命令来修改配置。
语法
CONFIG SET 命令基本语法:
- redis 127.0.0.1 : 6379 > CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
实例
- redis 127.0.0.1:6379> CONFIG SET loglevel "notice"
- OK
- redis 127.0.0.1:6379> CONFIG GET loglevel
- 1) "loglevel"
- 2) "notice"
redis.conf 配置项说明如下:
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize no
2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid
3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字
port 6379
4. 绑定的主机地址
bind 127.0.0.1
5.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 300
6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
logfile stdout
8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save <seconds> <changes>
Redis默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
11. 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
12. 指定本地数据库存放目录
dir ./
13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
slaveof <masterip> <masterport>
14. 当master服务设置了密码保护时,slav服务连接master的密码
masterauth <master-password>
15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
requirepass foobared
16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
maxclients 128
17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
maxmemory <bytes>
18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
appendonly no
19. 指定更新日志文件名,默认为appendonly.aof
appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)
vm-enabled no
22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
vm-swap-file /tmp/redis.swap
23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0
vm-max-memory 0
24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值
vm-page-size 32
25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
vm-pages 134217728
26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4
vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)
activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
include /path/to/local.conf
由于Redis是基于内存的数据库,为了保证数据的可用性,Redis提供了两种数据持久化机制:RDB和AOF,下面对这两种持久化方式加以分析。
RDB模式可以在指定的时间间隔内生成内存中整个数据集的持久化快照。快照文件默认被存储在当前文件夹中,名称为dump.rdb,可以通过dir和dbfilename参数来修改默认值。
- .redis调用fork函数复制当前进行的一个副本-子进程
- .父进程继续接收并处理客户端发来的命令
- .子进行将内存中的数据写入一个临时的dump文件
- .子进程写入完成后,会用新的临时dump文件替换就的rdb文件
- .一次持久化完成
在执行fork函数的时候,操作系统会使用写时复制(copy-on-write)策略,也就是说在调用fork的一刻,父子进行有相同的内存模型,当父进程要修改其中的某片数据时,操作系统会将该片数据复制一份,从而保证不影响子进程。
rdb文件是经过压缩的文件,占用的空间比较小,更有利于传输,并且数据恢复速度也比较快。
1.rdb持久化文件很紧凑,占用空间更小。
2.rdb保存的是基于时间点的数据快照,更适合数据的备份和容灾
3.利用rdb文件进行数据恢复时,速度更快
1.会造成部分数据的丢失
2.当数据集非常大时,fork操作会占用很多系统资源,造成主服务进程假死
1.数据备份
2.可容忍部分数据丢失
3.跨数据中心的容灾备份
aof持久化 记录服务器的所有写操作,并在服务器启动时重新执行这些命令来恢复数据集。aof文件中的命令全部以redis的协议格式存储,新命令会追加到文件的末尾,同时,redis还会在后台对aof文件进行重写,使得aof文件的体积不会过大。
aof机制默认关闭,可以通过
参数开启aof机制,通过
- appendonly = yes
指定aof文件名称。
- appendfilename = myaoffile.aof
对于触发aof重写机制也可以通过配置文件来进行设置:
- auto-aof-rewrite-percenttage = 100
- auto-aof-rewrite-min-size 64mb
第一个参数是配置较前一个aof文件大小增长的百分比,第二个参数是配置触发aof重写的aof的最小的大小。
修改aof的fsync策略:
- appendfsync=always 同步持久化每一次修改操作
- appendfsync=everysec 每秒想aof文件同步一次
- appendfsync=no 关闭向aof文件写入修改
1.支持不同的fsync策略:no/always/everysec
2.能够记录所有写操作,不会造成数据丢失
3.aof重写机制确保aof文件不会过大
4.aof文件可以很容易的读懂
1.虽然有aof重写机制,单aof文件通常比rdb文件大
2.在不同的fsync策略写,redis性能会受到一定影响
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
一个事务从开始到执行会经历以下三个阶段:
以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:
- redis 127.0.0.1:6379> MULTI
- OK
- redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
- QUEUED
- redis 127.0.0.1:6379> GET book-name
- QUEUED
- redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
- QUEUED
- redis 127.0.0.1:6379> SMEMBERS tag
- QUEUED
- redis 127.0.0.1:6379> EXEC
- 1) OK
- 2) "Mastering C++ in 21 days"
- 3) (integer) 3
- 4) 1) "Mastering Series"
- 2) "C++"
- 3) "Programming"
- 1 DISCARD
- 取消事务,放弃执行事务块内的所有命令。
- 2 EXEC
- 执行所有事务块内的命令。
- 3 MULTI
- 标记一个事务块的开始。
- 4 UNWATCH
- 取消 WATCH 命令对所有 key 的监视。
- 5 WATCH key [key ...]
- 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
以下实例演示了发布订阅是如何工作的。在我们实例中我们创建了订阅频道名为 redisChat:
- redis 127.0.0.1:6379> SUBSCRIBE redisChat
- Reading messages... (press Ctrl-C to quit)
- 1) "subscribe"
- 2) "redisChat"
- 3) (integer) 1
现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。
- redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
- (integer) 1
- redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"
- (integer) 1
- # 订阅者的客户端会显示如下消息
- 1) "message"
- 2) "redisChat"
- 3) "Redis is a great caching technique"
- 1) "message"
- 2) "redisChat"
- 3) "Learn redis by runoob.com"
- 1 PSUBSCRIBE pattern [pattern ...]
- 订阅一个或多个符合给定模式的频道。
- 2 PUBSUB subcommand [argument [argument ...]]
- 查看订阅与发布系统状态。
- 3 PUBLISH channel message
- 将信息发送到指定的频道。
- 4 PUNSUBSCRIBE [pattern [pattern ...]]
- 退订所有给定模式的频道。
- 5 SUBSCRIBE channel [channel ...]
- 订阅给定的一个或多个频道的信息。
- 6 UNSUBSCRIBE [channel [channel ...]]
- 指退订给定的频道。
Redis从单机到集群,一步步教你环境部署以及使用
1、停止使用 KEYS *
Okay,以挑战这个命令开始这篇文章,或许并不是一个好的方式,但其确实可能是最重要的一点。很多时候当我们关注一个redis实例的统计数据,我们会快速地输入”KEYS *”命令,这样key的信息会很明显地展示出来。平心而论,从程序化的角度出发往往倾向于写出下面这样的伪代码:
- for key in'keys *':
- doAllTheThings()
但是当你有1300万个key时,执行速度将会变慢。因为KEYS命令的时间复杂度是O(n),其中n是要返回的keys的个数,这样这个命令的复杂度就取决于数据库的大小了。并且在这个操作执行期间,其它任何命令在你的实例中都无法执行。
作为一个替代命令,看一下 SCAN 吧,其允许你以一种更友好的方式来执行… SCAN 通过增量迭代的方式来扫描数据库。这一操作基于游标的迭代器来完成的,因此只要你觉得合适,你可以随时停止或继续。
2、找出拖慢 Redis 的罪魁祸首
由于 Redis 没有非常详细的日志,要想知道在 Redis 实例内部都做了些什么是非常困难的。幸运的是 Redis 提供了一个下面这样的命令统计工具:
- 127.0.0.1:6379> INFO commandstats
- # Commandstats
- cmdstat_get:calls=78,usec=608,usec_per_call=7.79
- cmdstat_setex:calls=5,usec=71,usec_per_call=14.20
- cmdstat_keys:calls=2,usec=42,usec_per_call=21.00
- cmdstat_info:calls=10,usec=1931,usec_per_call=193.10
通过这个工具可以查看所有命令统计的快照,比如命令执行了多少次,执行命令所耗费的毫秒数(每个命令的总时间和平均时间)
只需要简单地执行 CONFIG RESETSTAT 命令就可以重置,这样你就可以得到一个全新的统计结果。
3、 将 Redis-Benchmark 结果作为参考,而不要一概而论
Redis 之父 Salvatore 就说过:“通过执行GET/SET命令来测试Redis就像在雨天检测法拉利的雨刷清洁镜子的效果”。很多时候人们跑到我这里,他们想知道为什么自己的Redis-Benchmark统计的结果低于最优结果 。但我们必须要把各种不同的真实情况考虑进来,例如:
Redis-Benchmark的测试结果提供了一个保证你的 Redis-Server 不会运行在非正常状态下的基准点,但是你永远不要把它作为一个真实的“压力测试”。压力测试需要反应出应用的运行方式,并且需要一个尽可能的和生产相似的环境。
4、Hashes 是你的最佳选择
以一种优雅的方式引入 hashes 吧。hashes 将会带给你一种前所未有的体验。之前我曾看到过许多类似于下面这样的key结构:
- foo:first_name
- foo:last_name
- foo:address
上面的例子中,foo 可能是一个用户的用户名,其中的每一项都是一个单独的 key。这就增加了 犯错的空间,和一些不必要的 key。使用 hash 代替吧,你会惊奇地发现竟然只需要一个 key :
- 127.0.0.1:6379> HSET foo first_name "Joe"(integer) 1
- 127.0.0.1:6379> HSET foo last_name "Engel"(integer) 1
- 127.0.0.1:6379> HSET foo address "1 Fanatical Pl"(integer) 1
- 127.0.0.1:6379> HGETALL foo
- 1)"first_name"
- 2)"Joe"
- 3)"last_name"
- 4)"Engel"
- 5)"address"
- 6)"1 Fanatical Pl"
- 127.0.0.1:6379> HGET foo first_name
- "Joe"
5、设置 key 值的存活时间
无论什么时候,只要有可能就利用key超时的优势。一个很好的例子就是储存一些诸如临时认证key之类的东西。当你去查找一个授权key时——以OAUTH为例——通常会得到一个超时时间。这样在设置key的时候,设成同样的超时时间,Redis就会自动为你清除!而不再需要使用KEYS *来遍历所有的key了,怎么样很方便吧?
6、 选择合适的回收策略
既然谈到了清除key这个话题,那我们就来聊聊回收策略。当 Redis 的实例空间被填满了之后,将会尝试回收一部分key。根据你的使用方式,我强烈建议使用 volatile-lru 策略——前提是你对key已经设置了超时。但如果你运行的是一些类似于 cache 的东西,并且没有对 key 设置超时机制,可以考虑使用 allkeys-lru 回收机制。我的建议是先在这里查看一下可行的方案。
7、如果你的数据很重要,请使用 Try/Except
如果必须确保关键性的数据可以被放入到 Redis 的实例中,我强烈建议将其放入 try/except 块中。几乎所有的Redis客户端采用的都是“发送即忘”策略,因此经常需要考虑一个 key 是否真正被放到 Redis 数据库中了。至于将 try/expect 放到 Redis 命令中的复杂性并不是本文要讲的,你只需要知道这样做可以确保重要的数据放到该放的地方就可以了。
8、不要耗尽一个实例
无论什么时候,只要有可能就分散多redis实例的工作量。从3.0.0版本开始,Redis就支持集群了。Redis集群允许你基于key范围分离出部分包含主/从模式的key。完整的集群背后的“魔法”可以在这里找到。但如果你是在找教程,那这里是一个再适合不过的地方了。如果不能选择集群,考虑一下命名空间吧,然后将你的key分散到多个实例之中。关于怎样分配数据,在redis.io网站上有这篇精彩的评论。
9、内核越多越好吗?!
当然是错的。Redis 是一个单线程进程,即使启用了持久化最多也只会消耗两个内核。除非你计划在一台主机上运行多个实例——希望只会是在开发测试的环境下!——否则的话对于一个 Redis 实例是不需要2个以上内核的。
10、高可用
到目前为止 Redis Sentinel 已经经过了很全面的测试,很多用户已经将其应用到了生产环境中(包括 ObjectRocket )。如果你的应用重度依赖于 Redis ,那就需要想出一个高可用方案来保证其不会掉线。当然,如果不想自己管理这些东西,ObjectRocket 提供了一个高可用平台,并提供7×24小时的技术支持,有意向的话可以考虑一下。
使用 jedis.jar
链接测试:
- package redis;
- import redis.clients.jedis.Jedis;
- public class RedisJava {
- public static void main(String[] args) {
- //连接本地的 Redis 服务
- Jedis jedis = new Jedis("localhost");
- System.out.println("连接成功");
- //查看服务是否运行
- System.out.println("服务正在运行: " + jedis.ping());
- jedis.close();
- }
- }
String:
- package redis;
- import redis.clients.jedis.Jedis;
- public class RedisStringJava {
- public static void main(String[] args) {
- //连接本地的 Redis 服务
- Jedis jedis = new Jedis("localhost");
- System.out.println("连接成功");
- //设置 redis 字符串数据
- jedis.set("name", "loveincode");
- // 获取存储的数据并输出
- System.out.println("redis 存储的字符串为: " + jedis.get("name"));
- jedis.close();
- }
- }
使用Spring + Jedis集成Redis
学习笔记部分来自菜鸟教程:http://www.runoob.com/redis/ 、redis持久化:http://blog.csdn.net/zhangdong2012/article/details/53116213
来源: http://www.cnblogs.com/loveincode/p/7508781.html