標籤:style http color os 使用 io strong 檔案 for
Redis 伺服器
Remote Dictionay Server Redis是一個key-value持久化產品,通常被稱為資料結構伺服器。 Redis的key是string類型;value可以是string、hash、list、set、sorted set等類型;實際上,Redis內部會將key和value都以二進位位元組流的格式儲存。
安裝
redis:
redis官網:
http://code.google.com/p/redis/
安裝方法:
http://code.google.com/p/redis/wiki/QuickStart
$ tar xvzf redis-1.02.tar.gz
$ cd redis-1.02
$ make $ make test
部署:
將redis-cli redis-benchmark redis-server redis.conf靠到指定的目錄。
修改設定檔:
在redis.conf可以指定db的儲存路徑,預設是儲存在目前的目錄。具體內容見redis.conf中的注釋。
啟動:
./redis-server
KEY操作 exists key 測試key是否存在,返回1存在,0不存在dbsize 當前資料庫的key數量dump key 返回被序列化的值del key1 key2 ... 刪除給定的key,返回刪除key的數目type key 返回給定key的value類型,返回none表示不存在keykeys patten 返回匹配指定模式的所有keyrandomkey 返回一個隨機播放的keyrename oldkey newkey 重新命名一個key,如果newkey存在將會被覆蓋renamenx oldkey newkey 重新命名一個key,如果newkey存在返回失敗expire key seconds 為key指定到期時間,相對時間expireat key timestamp 為key指定到期時間,絕對時間(UNIX時間)ttl key 返回設定到期時間的key的剩餘到期秒數persist key 移除key的到期時間
VALUE的
五種
資料結構
1、string(字串) set key value 插入一條資料(key-value pair),若key已存在,則覆蓋舊valueappend key value 對已存在的key,在其value末尾添加新資料;如key不存在,等效於set命令setex key seconds value 原子性完成兩個操作,一是設定key值為指定value,同時設定該key的ttlsetnx key val key不存在時才插入該記錄 get key 按鍵索引資料,如key不存在,返回nilgetset key value 將key設定為新的value,並返回舊valuemget key1 key2 返回多個key的值mset key1 val1 key2 val2getrange key start end 返回value的一個切片,雙閉區間setrange key offset value 替換key的部分字串值substr key start end getbit setbit strlen key value長度incr key value++(原子操作),將value當成整型處理incrby key n value+=ndecr key value--decrby key n value-=n
2、hash(雜湊表)雜湊表結構 hset table field valuehmset table field1 val1 field2 val2 ... hget table fieldhmget table field1 field2 field3 ... hdel table field hgetall tablehkeys tablehvals table
3、list(列表)FIFO結構,用鏈表實現,支援快速插入元素,但尋找效能比較低 lpush list node 在list頭部插入rpush list node 在list尾部插入lpop list 在list頭部刪除rpop list 在list尾部刪除 linsert list before val_b node 在val_b前插入新元素vallrange list start end 返回list的一個切片 list[start:end],雙閉區間,索引可以為負數,-1表示最後一個元素,-2表示倒數第二個元素ltrim list start end 對list進行裁減,只保留指定範圍內的元素llen list list長度
4、set(集合)將一系列不重複的值儲存成一個集合 sadd set element 往集合中添加元素srem set element 從集合中刪除指定元素smembers set 返回集合所有元素sinter set1 set2 取交集sunion set1 set2 取並集sdiff set1 set2 取差集
5、sorted set(有序集合)與set類似,但sorted set中的資料有一個score屬性,集合中的所有元素按照其score排序。sorted set採用了skip list結構的實現,插入一個元素的時間複雜度是O(logN) zadd sorted_set score member 添加元素,並指定scorezscore sorted_set member 返回指定元素的scorezrange sorted_set start end [withscores] 返回從start到end次序的元素,zrange sorted_set 0 -1 返回所有memberzrevrange sorted_set start end 反序,按score從大到小的順序返回zrangebyscore sorted_set min_score max_score 返回score在指定範圍內的元素zcard sorted_set 返回集合中的元素個數zcount sorted_set min max 返回集合中在指定分數範圍內的元素個數 zremrangebyscore sorted_set min_score max_score 刪除score在指定範圍內的元素zrank sorted_set member 返回元素在集合中的排名(從0開始計算)zincrby sorted_set increment member 為指定元素的score加上一個增量incrementzrem sorted_set member 刪除指定元素
6、publish/subscribe(訂閱)可以將資料推送到某個資訊管道中,然後其他人可以通過訂閱這些管道來擷取推送過來的資訊。 publish channlone keysubscribe channlone
常用命令:info 列印redis資訊select n 選取資料庫(預設支援16個db)move key n 將key從當前庫移至指定資料庫flushdb 清空當前資料庫flushall 清空所有資料庫config get parameter 讀取伺服器的運行時參數(redis.conf檔案中的配置項)config set parameter value 重新設定運行時參數 save 儲存資料快照(dump.rdb)bgsavebgrewriteaof 壓縮aof持久化檔案 shutdown 停止所有用戶端,同時以阻塞的方式執行記憶體資料持久化slaveof host port 修改SLAVE伺服器的複製設定
管線(pipelining) 用戶端在發送命令之後,不用立即等待來自伺服器的響應,而是可以繼續發送後面的命令,在命令發送完畢之後,再一次性的讀取之前所有命令的應答。
持久化(persistence) Redis 的資料持久化是通過將記憶體中的資料同步到磁碟來實現的,Redis支援兩種持久化方式:1、
Snapshotting,將記憶體中的資料以快照方式寫入二進位檔案中,預設檔案名稱為dump.rdb。 相關配置:save seconds changed # 在指定時間內,如果超過changed個key被修改,則發起快照儲存 快照儲存過程:
- fork一個子進程,父進程繼續處理client請求,子進程負責將記憶體內容寫入臨時檔案;
- 由於os的寫時複製技術(copy on write),當父進程處理寫請求時,os會為其要修改的頁面棄置站台,所以子進程的地址空間資料是fork時刻整個資料庫的一個快照;
- 子進程將快照寫入臨時檔案完畢後,用臨時檔案替換原來的快照檔案,然後子進程退出。
使用snap shot方式,當Redis實體記憶體使用超過記憶體總量的3/5時就會開始有crash的風險。fork調用的copy-on-write機制是基於作業系統頁這個單位的,也就是只有寫入的髒頁會被複製,通常系統不會在短時間內所有頁都發生了寫入而導致複製。crash的真正原因是持久化使用了Buffer IO,所謂Buffer IO是指Redis對持久化檔案的寫入和讀取操作都會使用實體記憶體的Page Cache。 2、
Append-only file(aof),快照方式實在一定間隔時間做一次,如果redis發送了意外crash,就會丟失最後一次快照後的所有修改。 aof方式會將每一個收到的寫命令通過write函數追加到檔案中(預設是appendonly.aof),當redis重啟時通過重新執行檔案中儲存的寫命令來在記憶體中重建整個資料庫的內容。 相關配置:appendonly yes # 啟用aof持久化方式;appendfsync always # 每次收到寫命令就立即強制寫入磁碟,最慢,但是保證完全的持久化;appendfsync everysec # 每秒強制寫入磁碟一次appendfsync no # 依賴os核心自身的緩衝機制 redis-check-aof --fix <filename> # 修複損壞的AOF檔案 aof方式類似mysql的基於語句的binlog方式,可能會導致log檔案體積過大,當系統重啟恢複資料時如果是aof方式則載入資料會非常慢。
事務(transactions) 事務特徵:1、在事務中的所有命令都會被序列化的順序執行,事務執行期間,Redis不會再為client的請求提供任何服務,從而保證事務中的所有命令被原子的執行;2、Redis事務中如果有一條命令執行失敗,其後的命令仍然會繼續執行;3、當使用aof模式時,Redis會將事務內的所有寫操作在本次調用中全部寫入磁碟,如果在寫入的過程中出現崩潰(如斷電),那麼此時也許只有部分資料被寫入磁碟,Redis伺服器在重新啟動時執行一系列必要的一致性檢測,如果發現問題,可以將已寫入的部分資料進行復原。 事務的提交和復原操作:1、multi...exec的命令組合類別似於關聯式資料庫的BEGIN TRANSACTION ... COMMIT語句;watch key1, key2...multi cmd1cmd2...exec 2、multi...discard的命令組合類別似於關聯式資料庫的BEGIN TRANSACTION ... ROLLBACK語句;multicmd1cmd2...discard 在multi命令執行之前,可以使用watch命令指定待監控的keys;然後在執行EXEC之前,如果被監控的keys發生了修改(被其它用戶端更改了),EXEC將放棄執行該事務隊列中的所有命令。在事務中,可以使用unwatch命令取消當前事務監控的keys;如果已經執行了EXEC或DISCARD命令,則無需再手工執行unwatch命令,因為在此之後,事務中所有被監控的keys都將自動取消。
主從複製(replication) Replication的特徵:1、同一個Master可以同步多個Slaves;2、Master Server以非阻塞的方式為Slaves提供服務,因此,在主從同步期間,client仍可以提交查詢或修改請求;3、 Replication的工作原理:在Slave啟動並串連到Master之後,它將主動發送一個SYNC命令,此後Master將啟動後台存檔進程,同時收集所有接收到的用於修改資料集的命令,在後台進程執行完畢後,Master將傳送整個資料庫檔案到Slave,以完成一次完全同步。而Slave伺服器在接收到資料庫檔案資料之後將其存檔並載入記憶體中。此後, Master繼續將所有已收集到的修改命令,和新的修改命令一次傳送給Slaves,Slave將在本次執行這些資料修改命令,從而達到最終的資料同步。
虛擬記憶體( virtual memory) Redis的虛擬記憶體是為了保證key的尋找速度,只會將value交換到swap檔案中。因此,如果Redis的記憶體問題是由於太多value很小的key造成的,那麼虛擬記憶體並不解決問題。Redis沒有使用作業系統提供的虛擬記憶體機制,而是實現了自己的虛擬記憶體機制,主要是因為以下兩點:1、作業系統的虛擬記憶體是以4K頁面為最小單位進行的,而redis的大多數對象都遠小於4K;2、Redis可以將交換到磁碟的對象進行壓縮,一般壓縮後的對象回比記憶體中的對象小10倍; 相關配置:vm-enabled yes # 開啟虛擬記憶體功能vm-max-memory bytes # Redis使用的記憶體上限vm-swap-file path # 交換出來的value儲存的檔案路徑vm-page-size bytes # 頁面大小vm-pages number # 頁面數量的上限vm-max-threads num # 執行value換入換出的背景工作執行緒數量 一個value可以保持在多個page裡面,但一個page只能儲存一個value;在Redis使用的記憶體沒超過vm-max-memory之前是不會交換任何value的。當超過最大記憶體限制後,Redis優先選擇到期或較大的對象進行交換:swappablility = age * log(size_in_memory) vm-max-threads=0時,會啟用阻塞式虛擬記憶體,以同步方式執行I/O操作。
通訊協定(Protocol) http://www.redisdoc.com/en/latest/topic/protocol.html *<參數數量> CR LF$<參數 1 的位元組數量> CR LF
<參數 1 的資料> CR LF
...
$<參數 N 的位元組數量> CR LF
<參數 N 的資料> CR LF 注意:命令本身也作為協議的一個參數來傳送;比如:client要向server發送如下命令:set mykey myvalue則格式化成協議的資料為:"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n" Redis命令會返回不同類型的回複,每種類型的回複以第一個位元組區分:1、status reply: "+",例如:"+OK\r\n"2、error reply: "-",例如:"-ERR unknown command ‘foobar‘"3、interger reply: ":",例如:":1000\r\n"4、bulk reply: "$",例如:"$6\r\nfoobar\r\n"5、multi bulk reply: "*",例如:"*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n" status reply通常是由那些不需要返回資料的命令返回(如set命令),這種回複不是binary safe的; bulk reply用來返回binary safe字串,字串的最大長度為512M,常用於get命令的返回結果;如果請求的key不存在,會返回"$-1\r\n",這稱為NULL Bulk Reply; multi bulk reply常用於lrange這樣的命令,它返回多個值。Empty Multi Bulk Reply: "*0\r\n"NULL Multi Bulk Reply: "*-1\r\n"
C 用戶端官
官網:
http://github.com/redis/hiredis
安裝方法:
git clone https://github.com/redis/hiredis
$ cd hiredis
$ make $ make install
編譯:
以hiredis內建的example.c程式為例:
gcc -lhiredis example.c
Redis 快取服務器