1.介紹
REmote DIctionary Server(Redis) 是一個(gè)由Salvatore Sanfilippo寫的key-value存儲(chǔ)系統(tǒng)酿箭。
Redis是一個(gè)開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)冯勉、可基于內(nèi)存亦可持久化的日志型砂豌、Key-Value數(shù)據(jù)庫蛮寂,并提供多種語言的API。
它通常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器樟遣,因?yàn)橹担╲alue)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。
2.數(shù)據(jù)類型
- String:字符串
- Hash:哈希
- List:列表
- Set:集合
- ZSet(Sorted Sets): 有序集合
3. 下載安裝
最新版下載地址:http://redis.io/download
以下是在Ubuntu環(huán)境下進(jìn)行安裝
$ sudo apt-get update
$ sudo apt-get install redis-server
// 啟動(dòng)redis
$ redis-server
// 連接redis
$ redis-cli
127.0.0.1:6039> ping
PONG
注: 配置文件位于 /etc/redis.conf
4. 基本操作
- String: 字符串
Redis 最基本的數(shù)據(jù)類型身笤,string 類型是二進(jìn)制安全的豹悬,string可以是任何數(shù)據(jù)的序列化,最大能存儲(chǔ) 512MB液荸。
語法:
SET key value [EX seconds] [PX milliseconds] [NX|xx]
EX: 過期時(shí)間 秒
PX: 過期時(shí)間 毫秒
NX: 不過期
GET key : 獲取
DEL key : 刪除
實(shí)例:
127.0.0.1:6039> SET test "hello world"
OK
127.0.0.1:6379> GET test
"hello world"
127.0.0.1:6379> DEL test
(integer) 0
127.0.0.1:6379> GET test
(nil)
- Hash: 散列表
Redis hash 是一組鍵值(key=>value)對(duì)集合瞻佛。
Redis hash 是一個(gè) string 類型的 field 和 value 的映射表,hash 特別適合用于存儲(chǔ)對(duì)象娇钱。
語法:
HSET key field value
HGET key field
HMSET key field value [field value ...]
HMGET key field [field ...]
HDEL key filed [field ...]
HLEN key:獲取hash表的數(shù)量
HKEYS key: 獲取hash表中所有的字段
HVALS key: 獲取hash表中所有的值
HEXISTS key field:判斷字段是否存在
實(shí)例:
127.0.0.1:6379> HSET myobj name "redis"
(integer) 0
127.0.0.1:6379> HGET myobj name
"redis"
127.0.0.1:6379> HMSET myobj name "redis1" message "hello world redis1" count 1
OK
1) "redis1"
2) "hello world redis1"
3) "1"
127.0.0.1:6379> HDEL myobj name count
(integer) 2
127.0.0.1:6379> HMGET myobj name message count
1) (nil)
2) "hello world redis1"
3) (nil)
127.0.0.1:6379> HLEN myobj
(integer) 2
127.0.0.1:6379> HKEYS myobj
1) "message"
2) "type"
127.0.0.1:6379> HVALS myobj
1) "hello world redis1"
2) "test"
127.0.0.1:6379> HGETALL myobj
1) "message"
2) "hello world redis1"
3) "type"
4) "test"
127.0.0.1:6379> HEXISTS myobj name
(integer) 0
127.0.0.1:6379> HEXISTS myobj message
(integer) 1
- List: 列表
Redis 列表是簡單的字符串列表伤柄,按照插入順序排序。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)忍弛。
語法:
LPUSH key value [value ...]: 添加到頭部
LPOP key : 從頭部取數(shù)據(jù)
RPOP key : 從尾部取數(shù)據(jù)
RPUSH key value [value ...]: 添加到尾部
LRANGE key start stop: 讀取
LLEN key: 讀取list長度
實(shí)例:
127.0.0.1:6379> LPUSH list_left 1 2 3 5 7
(integer) 5
127.0.0.1:6379> LRANGE list_left 0 5
1) "7"
2) "5"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> LPOP list_left
"7"
127.0.0.1:6379> LRANGE list_left 0 4
1) "5"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> RPOP list_left
"1"
127.0.0.1:6379> LRANGE list_left 0 3
1) "5"
2) "3"
3) "2"
127.0.0.1:6379> LLEN list_left
(integer) 3
127.0.0.1:6379> RPUSH list_right 1 2 3 5 7
(integer) 5
127.0.0.1:6379> LRANGE list_right 0 5
1) "1"
2) "2"
3) "3"
4) "5"
5) "7"
- Set: 集合
Redis 的 Set 是 String 類型的無序集合响迂。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)细疚。
語法:
SADD key value [value ...]: 添加
SMEMBERS key : 讀取所有字段
SCARD key: 獲取集合長度
SINTER key1 [key ...] : 獲取集合的交集
SDIFF key1 [key ...]: 獲取key1 與其他集合的差集
SREM key member [member ...] : 移除集合中的元素
實(shí)例:
127.0.0.1:6379> SADD set_test redis rabbitmq redis
(integer) 2
127.0.0.1:6379> SMEMBERS set_test
1) "redis"
2) "rabbitmq"
127.0.0.1:6379> SADD set_test ABB
(integer) 1
127.0.0.1:6379> SMEMBERS set_test
1) "redis"
2) "ABB"
3) "rabbitmq"
127.0.0.1:6379> SCARD set_test
(integer) 3
127.0.0.1:6379> SADD set_test1 redis rocketmq ABB
(integer) 3
127.0.0.1:6379> SINTER set_test set_test1
1) "redis"
2) "ABB"
127.0.0.1:6379> SDIFF set_test set_test1
1) "rabbitmq"
127.0.0.1:6379> SDIFF set_test1 set_test
1) "rocketmq"
127.0.0.1:6379> SREM set_test redis
(integer) 1
127.0.0.1:6379> SMEMBERS set_test
1) "ABB"
2) "rabbitmq"
- ZSet: 有序集合
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員
不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)蔗彤。redis正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。
有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)疯兼。
當(dāng)items內(nèi)容大于64的時(shí)候同時(shí)使用了hash和skiplist兩種設(shè)計(jì)實(shí)現(xiàn)然遏,這是為排序和查找性能做的優(yōu)化。
這里的score可以認(rèn)為是權(quán)重吧彪,可用來處理優(yōu)先級(jí)的問題待侵。
語法:
ZADD key score1 member1 [score2 member2 ...]
ZCARD key
ZCOUNT key min max
ZRANGE key start stop [WITHSCORES]
ZREM key member [member ...]
ZSCORE key member
實(shí)例:
127.0.0.1:6379> ZADD zset_test 1 redis 2 mysql 2 mongodb 3 rabbitmq
(integer) 4
127.0.0.1:6379> ZRANGE zset_test 0 4 WITHSCORES
1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "2"
7) "rabbitmq"
8) "3"
127.0.0.1:6379> ZSCORE zset_test mysql
"2"
5. 發(fā)布訂閱
Redis 發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息姨裸。
Redis 客戶端可以訂閱任意數(shù)量的頻道秧倾。
1. 暫定channel的名稱為 redisChat
2. 打開一個(gè)客戶端,訂閱redisChat
127.0.0.1:6379> SUBSCRIBE redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
# 訂閱客戶端收到的消息
1) "message"
2) "redisChat"
3) "Hello Redis"
1) "message"
2) "redisChat"
3) "Hello everyone, I am new"
3. 打開另外一個(gè)客戶端傀缩,往redisChat這個(gè)channel上發(fā)布消息
127.0.0.1:6379> PUBLISH redisChat "Hello Redis"
(integer) 1
4. 再打開一個(gè)客戶端那先,繼續(xù)往redisChat這個(gè)channel上發(fā)布消息
127.0.0.1:6379> PUBLISH redisChat "Hello everyone, I am new"
(integer) 1
6. Redis事務(wù)
單個(gè) Redis 命令的執(zhí)行是原子性的,但 Redis 沒有在事務(wù)上增加任何維持原子性的機(jī)制赡艰,所以 Redis 事務(wù)的執(zhí)行并不是原子性的售淡,目前僅是任務(wù)隊(duì)列,隊(duì)列中的某條指令失敗,不會(huì)回滾 Transactions doc
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set m1 I
QUEUED
127.0.0.1:6379> SADD mset I am a new person
QUEUED
127.0.0.1:6379> get m1
QUEUED
127.0.0.1:6379> SMEMBERS mset
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (integer) 5
3) "I"
4) 1) "new"
2) "a"
3) "I"
4) "am"
5) "person"
7. 數(shù)據(jù)備份與恢復(fù)
語法:
CONFIG GET dir : 獲取默認(rèn)備份位置
SAVE: 當(dāng)前數(shù)據(jù)庫的備份
BGSAVE: 當(dāng)前數(shù)據(jù)庫的后臺(tái)備份
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/var/db/redis"
127.0.0.1:6379> keys *
1) "zset_test"
2) "m1"
3) "myobj"
4) "set_test"
5) "list_left"
6) "mset"
7) "list_test"
8) "list_right"
9) "set_test1"
127.0.0.1:6379> SAVE
OK
將會(huì)在redis安裝目錄下生成 dump.rdb揖闸,備份時(shí)只需要將該文件移動(dòng)到 /usr/local/var/db/redis揍堕,重啟服務(wù)即可。
注: 還有一種策略叫做 AOF汤纸,即將發(fā)送到Redis服務(wù)端的每一條命令都記錄下來衩茸,并且保存到硬盤中的AOF文件中,類似打日志文件蹲嚣,來一條命令就記錄一條递瑰。
RDB:
優(yōu)點(diǎn):適合備份,文件小隙畜,速度快(大量數(shù)據(jù)時(shí))
缺點(diǎn):每隔一段時(shí)間保存一次抖部,所以當(dāng)系統(tǒng)宕機(jī)時(shí),可能會(huì)損失幾分鐘的數(shù)據(jù)
AOF:
優(yōu)點(diǎn):數(shù)據(jù)不會(huì)丟失
缺點(diǎn):文件大议惰,速度慢(大量數(shù)據(jù)時(shí))
8. 安全
redis默認(rèn)是免密慎颗,非常不安全,我們可以設(shè)置密碼進(jìn)行保護(hù)
語法:
CONFIG set requirepass "password"
實(shí)例:
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> CONFIG set requirepass password
OK
127.0.0.1:6379> CONFIG get requirepass
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH password
OK
// 或者重新登錄或者
? ~ redis-cli -a password
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) "password"
9. 性能測試
語法:
redis-benchmark [option] [option value]
實(shí)例:
? ~ redis-benchmark -n 10000 -q
PING_INLINE: 84033.61 requests per second
PING_BULK: 85470.09 requests per second
SET: 85470.09 requests per second
GET: 85470.09 requests per second
INCR: 86956.52 requests per second
LPUSH: 86956.52 requests per second
RPUSH: 86956.52 requests per second
LPOP: 85470.09 requests per second
RPOP: 86206.90 requests per second
SADD: 86956.52 requests per second
SPOP: 87719.30 requests per second
LPUSH (needed to benchmark LRANGE): 86956.52 requests per second
LRANGE_100 (first 100 elements): 26737.97 requests per second
LRANGE_300 (first 300 elements): 11235.96 requests per second
LRANGE_500 (first 450 elements): 7824.73 requests per second
LRANGE_600 (first 600 elements): 5959.48 requests per second
MSET (10 keys): 81300.81 requests per second
10. 管道技術(shù)
Redis是一種基于客戶端-服務(wù)端模型以及請(qǐng)求/響應(yīng)協(xié)議的TCP服務(wù)言询。這意味著通常情況下一個(gè)請(qǐng)求會(huì)遵循以下步驟:
- 客戶端向服務(wù)端發(fā)送一個(gè)查詢請(qǐng)求俯萎,并監(jiān)聽Socket返回,通常是以阻塞模式运杭,等待服務(wù)端響應(yīng)夫啊。
- 服務(wù)端處理命令,并將結(jié)果返回給客戶端辆憔。
Redis 管道技術(shù)可以在服務(wù)端未響應(yīng)時(shí)撇眯,客戶端可以繼續(xù)向服務(wù)端發(fā)送請(qǐng)求,并最終一次性讀取所有服務(wù)端的響應(yīng)虱咧,極大的提高了Redis的性能熊榛。
? ~ (echo -en "PING\r\n SET runoobkey redis\r\nGET runoobkey\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | redis-cli -a password
PONG
OK
"redis"
(integer) 4
(integer) 5
(integer) 6
注:參考runoob.com