標籤:blog http os io 使用 strong ar for 檔案
雖然Redis已經很火了,相信還是有很多同學對Redis只是有所聽聞或者瞭解並不全面,下面是一個比較系統的Redis介紹,對Redis的特性及各種資料類型及操作進行了介紹。是一個很不錯的Redis入門教程。
1.介紹1.1 Redis是什麼
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。Redis提供了一些豐富的資料結構,包括 lists, sets, ordered sets 以及 hashes ,當然還有和Memcached一樣的 strings結構.Redis當然還包括了對這些資料結構的豐富操作。
1.2 Redis的優點
- 效能極高 – Redis能支援超過 100K+ 每秒的讀寫頻率。
- 豐富的資料類型 – Redis支援二進位案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料類型操作。
- 原子 – Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全並後的原子性執行。
- 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 到期等等特性。
2.資料類型2.1 String類型
Redis能儲存二進位安全的字串,最大長度為1GB
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> GET name"John Doe"
String類型還支援批量的讀寫操作
redis 127.0.0.1:6379> MSET age 30 sex "male"OKredis 127.0.0.1:6379> MGET age sex1) "30"2) "male"
String類型其實也可以用來儲存數字,並支援對數位加減操作。
redis 127.0.0.1:6379> INCR age(integer) 31redis 127.0.0.1:6379> INCRBY age 4(integer) 35redis 127.0.0.1:6379> GET age"35"redis 127.0.0.1:6379> DECR age(integer) 34redis 127.0.0.1:6379> DECRBY age 4(integer) 30redis 127.0.0.1:6379> GET age"30"
String類型還支援對其部分的修改和擷取操作
redis 127.0.0.1:6379> APPEND name " Mr."(integer) 12redis 127.0.0.1:6379> GET name"John Doe Mr."redis 127.0.0.1:6379> STRLEN name(integer) 12redis 127.0.0.1:6379> SUBSTR name 0 3"John"
2.2 List類型
Redis能夠將資料存放區成一個鏈表,並能對這個鏈表進行豐富的操作
redis 127.0.0.1:6379> LPUSH students "John Doe"(integer) 1redis 127.0.0.1:6379> LPUSH students "Captain Kirk"(integer) 2redis 127.0.0.1:6379> LPUSH students "Sheldon Cooper"(integer) 3redis 127.0.0.1:6379> LLEN students(integer) 3redis 127.0.0.1:6379> LRANGE students 0 21) "Sheldon Cooper"2) "Captain Kirk"3) "John Doe"redis 127.0.0.1:6379> LPOP students"Sheldon Cooper"redis 127.0.0.1:6379> LLEN students(integer) 2redis 127.0.0.1:6379> LRANGE students 0 11) "Captain Kirk"2) "John Doe"redis 127.0.0.1:6379> LREM students 1 "John Doe"(integer) 1redis 127.0.0.1:6379> LLEN students(integer) 1redis 127.0.0.1:6379> LRANGE students 0 01) "Captain Kirk"
Redis也支援很多修改操作
redis 127.0.0.1:6379> LINSERT students BEFORE "Captain Kirk" "Dexter Morgan"(integer) 3redis 127.0.0.1:6379> LRANGE students 0 21) "Dexter Morgan"2) "Captain Kirk"3) "John Doe"redis 127.0.0.1:6379> LPUSH students "Peter Parker"(integer) 4redis 127.0.0.1:6379> LRANGE students 0 31) "Peter Parker"2) "Dexter Morgan"3) "Captain Kirk"4) "John Doe"redis 127.0.0.1:6379> LTRIM students 1 3OKredis 127.0.0.1:6379> LLEN students(integer) 3redis 127.0.0.1:6379> LRANGE students 0 21) "Dexter Morgan"2) "Captain Kirk"3) "John Doe"redis 127.0.0.1:6379> LREM students 1 "John Doe"(integer) 1redis 127.0.0.1:6379> LLEN students(integer) 1redis 127.0.0.1:6379> LRANGE students 0 11) "Captain Kirk"
2.3 集合(Sets)類型
Redis能夠將一系列不重複的值儲存成一個集合
redis 127.0.0.1:6379> SADD birds crow(integer) 1redis 127.0.0.1:6379> SADD birds pigeon(integer) 1redis 127.0.0.1:6379> SADD birds bat(integer) 1redis 127.0.0.1:6379> SADD mammals dog(integer) 1redis 127.0.0.1:6379> SADD mammals cat(integer) 1redis 127.0.0.1:6379> SADD mammals bat(integer) 1redis 127.0.0.1:6379> SMEMBERS birds1) "bat"2) "crow"3) "pigeon"redis 127.0.0.1:6379> SMEMBERS mammals1) "bat"2) "cat"3) "dog"
Sets結構也支援相應的修改操作
redis 127.0.0.1:6379> SREM mammals cat(integer) 1redis 127.0.0.1:6379> SMEMBERS mammals1) "bat"2) "dog"redis 127.0.0.1:6379> SADD mammals human(integer) 1redis 127.0.0.1:6379> SMEMBERS mammals1) "bat"2) "human"3) "dog"
Redis還支援對集合的子交並補等操作
redis 127.0.0.1:6379> SINTER birds mammals1) "bat"redis 127.0.0.1:6379> SUNION birds mammals1) "crow"2) "bat"3) "human"4) "pigeon"5) "dog"redis 127.0.0.1:6379> SDIFF birds mammals1) "crow"2) "pigeon"
2.4 有序集合(Sorted Sets)類型
Sorted Sets和Sets結構相似,不同的是存在Sorted Sets中的資料會有一個score屬性,並會在寫入時就按這個score排好序。
redis 127.0.0.1:6379> ZADD days 0 mon(integer) 1redis 127.0.0.1:6379> ZADD days 1 tue(integer) 1redis 127.0.0.1:6379> ZADD days 2 wed(integer) 1redis 127.0.0.1:6379> ZADD days 3 thu(integer) 1redis 127.0.0.1:6379> ZADD days 4 fri(integer) 1redis 127.0.0.1:6379> ZADD days 5 sat(integer) 1redis 127.0.0.1:6379> ZADD days 6 sun(integer) 1redis 127.0.0.1:6379> ZCARD days(integer) 7redis 127.0.0.1:6379> ZRANGE days 0 61) "mon"2) "tue"3) "wed"4) "thu"5) "fri"6) "sat"7) "sun"redis 127.0.0.1:6379> ZSCORE days sat"5"redis 127.0.0.1:6379> ZCOUNT days 3 6(integer) 4redis 127.0.0.1:6379> ZRANGEBYSCORE days 3 61) "thu"2) "fri"3) "sat"4) "sun"
2.5 Hash類型
Redis能夠儲存key對多個屬性的資料(比如user1.uname user1.passwd)
redis 127.0.0.1:6379> HKEYS student1) "name"2) "age"3) "sex"redis 127.0.0.1:6379> HVALS student1) "Ganesh"2) "30"3) "Male"redis 127.0.0.1:6379> HGETALL student1) "name"2) "Ganesh"3) "age"4) "30"5) "sex"6) "Male"redis 127.0.0.1:6379> HDEL student sex(integer) 1redis 127.0.0.1:6379> HGETALL student1) "name"2) "Ganesh"3) "age"4) "30"
Hash資料結構能夠批量修改和擷取
redis 127.0.0.1:6379> HMSET kid name Akshi age 2 sex FemaleOKredis 127.0.0.1:6379> HMGET kid name age sex1) "Akshi"2) "2"3) "Female"
3.Publish/Subscribe
Redis支援這樣一種特性,你可以將資料推到某個資訊管道中,然後其它人可以通過訂閱這些管道來擷取推送過來的資訊。
3.1 訂閱資訊管道
用一個客訂閱管道
redis 127.0.0.1:6379> SUBSCRIBE channeloneReading messages... (press Ctrl-C to quit)1) "subscribe"2) "channelone"3) (integer) 1
另一個用戶端往這個管道推送資訊
redis 127.0.0.1:6379> PUBLISH channelone hello(integer) 1redis 127.0.0.1:6379> PUBLISH channelone world(integer) 1
然後第一個用戶端就能擷取到推送的資訊
redis 127.0.0.1:6379> SUBSCRIBE channeloneReading messages... (press Ctrl-C to quit)1) "subscribe"2) "channelone"3) (integer) 11) "message"2) "channelone"3) "hello"1) "message"2) "channelone"3) "world"
3.2 按一定模式批量訂閱
用下面的命令訂閱所有channel開頭的資訊通道
redis 127.0.0.1:6379> PSUBSCRIBE channel*Reading messages... (press Ctrl-C to quit)1) "psubscribe"2) "channel*"3) (integer) 1
在另一個用戶端對兩個推送資訊
redis 127.0.0.1:6379> PUBLISH channelone hello(integer) 1redis 127.0.0.1:6379> PUBLISH channeltwo world(integer) 1
然後在第一個用戶端就能收到推送的資訊
redis 127.0.0.1:6379> PSUBSCRIBE channel*Reading messages... (press Ctrl-C to quit)1) "psubscribe"2) "channel*"3) (integer) 11) "pmessage"2) "channel*"3) "channelone"4) "hello"1) "pmessage"2) "channel*"3) "channeltwo"4) "world"
4.資料到期設定
Redis支援按key設定到期時間,到期後值將被刪除(在用戶端看來是補刪除了的)
用TTL命令可以擷取某個key值的到期時間(-1表示永不到期)
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> TTL name(integer) -1
下面命令先用EXISTS命令查看key值是否存在,然後設定了5秒的到期時間
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> EXISTS name(integer) 1redis 127.0.0.1:6379> EXPIRE name 5(integer) 1
5秒後再查看
redis 127.0.0.1:6379> EXISTS name(integer) 0redis 127.0.0.1:6379> GET name(nil)
這個值已經沒有了。
上在是直接設定多少秒後到期,你也可以設定在某個時間點到期,下面例子是設定2011-09-24 00:40:00到期。
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> EXPIREAT name 1316805000(integer) 1redis 127.0.0.1:6379> EXISTS name(integer) 0
5.事務性
Redis本身支援一些簡單的組合型的命令,比如以NX結尾命令都是判斷在這個值沒有時才進行某個命令。
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> SETNX name "Dexter Morgan"(integer) 0redis 127.0.0.1:6379> GET name"John Doe"
redis 127.0.0.1:6379> GETSET name "Dexter Morgan""John Doe"redis 127.0.0.1:6379> GET name"Dexter Morgan"
當然,Redis還支援自訂的命令組合,通過MULTI和EXEC,將幾個命令組合起來執行
redis 127.0.0.1:6379> SET counter 0OKredis 127.0.0.1:6379> MULTIOKredis 127.0.0.1:6379> INCR counterQUEUEDredis 127.0.0.1:6379> INCR counterQUEUEDredis 127.0.0.1:6379> INCR counterQUEUEDredis 127.0.0.1:6379> EXEC1) (integer) 12) (integer) 23) (integer) 3redis 127.0.0.1:6379> GET counter"3"
你還可以用DICARD命令來中斷執行中的命令序列
redis 127.0.0.1:6379> SET newcounter 0OKredis 127.0.0.1:6379> MULTIOKredis 127.0.0.1:6379> INCR newcounterQUEUEDredis 127.0.0.1:6379> INCR newcounterQUEUEDredis 127.0.0.1:6379> INCR newcounterQUEUEDredis 127.0.0.1:6379> DISCARDOKredis 127.0.0.1:6379> GET newcounter"0"
6.持久化
Redis的所有資料都儲存在記憶體中,但是他也提供對這些資料的持久化。
6.1 資料快照
資料快照的原理是將整個Redis中存的所有資料遍曆一遍存到一個副檔名為rdb的資料檔案中。通過SAVE命令可以調用這個過程。
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> SAVEOKredis 127.0.0.1:6379> SET name "Sheldon Cooper"OKredis 127.0.0.1:6379> BGSAVEBackground saving started
如果你是使用的brew在Mac OSX上安全的Redis,那麼rdb檔案會存在如下路徑
/usr/local/var/db/redis/dump.rdb
6.2 Append-Only File(追加式的動作記錄記錄)
Redis還支援一種追加式的動作記錄記錄,叫append only file,其記錄檔以aof結局,我們一般各為aof檔案。要開啟aof日誌的記錄,你需要在設定檔中進行如下設定:
appendonly yes
這時候你所有的操作都會記錄在aof記錄檔中
redis 127.0.0.1:6379> GET name(nil)redis 127.0.0.1:6379> SET name "Ganesh Gunasegaran"OKredis 127.0.0.1:6379> EXIT→ cat /usr/local/var/db/redis/appendonly.aof*2$6SELECT$10*3$3SET$4name$18Ganesh Gunasegaran
7.管理命令
Redis支援多個DB,預設是16個,你可以設定將資料存在哪一個DB中,不同DB間的資料具有隔離性。也可以在多個DB間移動資料。
redis 127.0.0.1:6379> SELECT 0OKredis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> SELECT 1OKredis 127.0.0.1:6379[1]> GET name(nil)redis 127.0.0.1:6379[1]> SELECT 0OKredis 127.0.0.1:6379> MOVE name 1(integer) 1redis 127.0.0.1:6379> SELECT 1OKredis 127.0.0.1:6379[1]> GET name"John Doe"
Redis還能進行一些如下操作,擷取一些運行資訊
redis 127.0.0.1:6379[1]> DBSIZE(integer) 1redis 127.0.0.1:6379[1]> INFOredis_version:2.2.13redis_git_sha1:00000000redis_git_dirty:0arch_bits:64multiplexing_api:kqueue......
Redis還支援對某個DB資料進行清除(當然清空所有資料的操作也是支援的)
redis 127.0.0.1:6379> SET name "John Doe"OKredis 127.0.0.1:6379> DBSIZE(integer) 1redis 127.0.0.1:6379> SELECT 1OKredis 127.0.0.1:6379[1]> SET name "Sheldon Cooper"OKredis 127.0.0.1:6379[1]> DBSIZE(integer) 1redis 127.0.0.1:6379[1]> SELECT 0OKredis 127.0.0.1:6379> FLUSHDBOKredis 127.0.0.1:6379> DBSIZE(integer) 0redis 127.0.0.1:6379> SELECT 1OKredis 127.0.0.1:6379[1]> DBSIZE(integer) 1redis 127.0.0.1:6379[1]> FLUSHALLOKredis 127.0.0.1:6379[1]> DBSIZE(integer) 0
8.用戶端
Redis的用戶端很豐富,幾乎所有流行的語言都有其用戶端,這裡就不再贅述,有興趣的同學可以上Redis的Clients頁面去尋找。
Redis系統性介紹