redis 手冊

redis安裝及配置

安裝

wget http://download.redis.io/releases/redis-3.0.7.tar.gz
tar zxvf redis-3.0.7.tar.gz
cd redis-3.0.7/
make
make install

安裝後,在/usr/local/bin下面有如下文件:

redis-server     服務器
redis-cli        命令行客戶端
redis-benchmark  性能測試工具
redis-check-aof  AOF文件修復工具
redis-check-dump RDB文件檢查工具

啓動

不指定配置文件啓動,在控制檯執行:redis-server

指定配置文件啓動,需要加上參數:redis-server /etc/myredis.conf

指定端口啓動:redis-server –port 6379

以salve方式啓動:redis-server –port 6380 –slaveof 127.0.0.1 6379

可以使用redis自帶的redis-cli作爲客戶端連接服務器

配置

  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_cli是redis自帶的命令行工具。

用法示例:

root@debian8:redis-3.0.7# redis-cli127.0.0.1:6379> keys *
(empty list or set)127.0.0.1:6379>

圖形管理工具

redis desktop

https://redisdesktop.com/

基本操作

這裏字符串類型爲例描述redis的基本操作命令,其它數據類型參考文檔。

  • SET

如果key不存在,該命令可以完成添加操作;如果key存在,該命令實現更新操作;

SET key value
  • GET

獲取某個key所對應的值,格式如下:

GET key
  • DEL

刪除操作,格式如下:

DEL key
  • KEYS

獲取符合規律的鍵名列表,格式如下:

KEYS pattern

pattern支持glob風格通配符格式,具體如下:

?       匹配一個字符
*       匹配任意個(包括0個)字符[]      匹配括號間的任一字符,可以使用"-"符號表示一個
        範圍,如a[b-d]可以匹配"ab","ac"和"ad"
\x      匹配字符x,用於轉義符號。
  • EXISTS

用於判斷一個鍵是否存在,格式:

EXISTS key
  • EXPIRE

設置key的超時時間TTL(Time To Live),生存時間到期後鍵會自動被刪除,格式:

EXPIRE key seconds

數據模型

Redis是REmote DIctionary Server(遠程字典服務器)的縮寫, 它以字典結構存儲數據,並允許其他應用通過TCP協議讀寫字典中的內容。 同大多數腳本語言中的字典一樣,Redis字典中的鍵值除了可以是字符串,還可以是其他數據類型。 到目前爲止 Redis 支持的鍵值數據類型如下:

字符串類型

字符串是redis最基礎的數據類型,它能存儲任何形式的字符串,包括二進制數據。 一個字符串類型鍵允許存儲的數據的最大容量是512M。 常用命令如下:

  • SET

賦值操作

SET key value

示例:

SET a 5 ==> OK
  • GET

取值操作

GET key

示例:

GET a  ==> "5"
  • INCR

遞增操作,鍵不存在時創建並賦0,否則+1

INCR key

示例:

INCR a ==> 6
  • DECR

遞減操作

DECR key

示例:

DECR a ==> 5
  • INCRBY

與incr一樣,不過可以指定增加的數值

INCRBY key num

示例:

INCRBY a 10   ==>  15
  • APPEND

追加,返回追加後字符串長度

APPEND key value

示例:

APPEND a 6  ==>  156
  • STRLEN

獲取字符串長度

STRLEN key

示例:

STRLEN a  ==> 3
  • MSET

同時設置多個鍵值

MSET key value[key2 value2 ...]

示例:

MSET key1 1 key2 2 ==> OK
  • MGET

同時獲取多個鍵值

MGET key1 key2 =>1) "1"2) "2"

其它string命令參考官方手冊 : http://redis.io/commands#string

散列類型

散列類型(hash)的鍵值也是一種字典結構,其存儲了字段(field)和字段值的映射, 但字段值只能是字符串,不支持其他數據類型,也就是散列類型不能嵌套其他的數據類型。

除了散列類型,Redis 的其他數據類型同樣不支持數據類型嵌套。比如集合類型的每個元素都只能是字符串,不能是另一個集合或散列表等。

散列類型適合存儲對象:使用對象類別和 ID 構成鍵名,使用字段表示對象的屬性, 而字段值則存儲屬性值。

常用命令如下:

  • HSET

設置或修改字段值

HSET key field value
  • HGET

獲取字段值

HGET key field
  • HMSET

同時設置多個字段

HMSET key field value [field value ...]
  • HMGET

同時獲取多個字段值

HMGET key field [field ...]
  • HGETALL

獲取鍵中所有字段和值

HGETALL key
  • HEXISTS

判斷字段是否存在,存在返回1,否則返回0(如果鍵不存在也返回0)

HEXISTS key field

其它hashs命令參考官方手冊 : http://redis.io/commands#hash

列表類型

列表類型(list)可以存儲一個有序的字符串列表,常用的操作是向列表兩端添加元素,或者獲得列表的某一個片段。

列表類型內部是使用雙向鏈表(double linked list)實現的,所以向列表兩端添加元素的時間複雜度爲O(1),獲取越接近兩端的元素速度就越快。 這意味着即使是一個有幾千萬個元素的列表,獲取頭部或尾部的10條記錄也是極快的(和從只有20個元素的列表中獲取頭部或尾部的10條記錄的速度是一樣的)。

這種特性使列表類型能非常快速地完成關係數據庫難以應付的場景: 如社交網站的新鮮事,我們關心的只是最新的內容,使用列表類型存儲, 即使新鮮事的總數達到幾千萬個,獲取其中最新的100條數據也是極快的。 同樣因爲在兩端插入記錄的時間複雜度是O(1),列表類型也適合用來記錄日誌,可以保證加入新日誌的速度不會受到已有日誌數量的影響。

常用命令如下:

  • LPUSH

向列表的左邊增加元素,返回增加元素後列表的長度

LPUSH key value[ value..]
  • RPUSH

向列表的右邊增加元素

RPUSH key value[ value..]
  • LPOP

從列表左邊移除一個元素,並返回該元素值

LPOP key
  • RPOP

從列表的右側移除一個元素,並返回該元素值

RPOP key
  • LLEN

返回列表元素個數,鍵不存在時返回0

LLEN key
  • LRANGE

獲取列表片段,start和stop支持負數,-1表示右數第一個

LRANGE key start stop
  • LREM

刪除列表中指定的值,返回刪除的元素個數

LREM key count value
  • LINDEX

獲取指定索引元素值

LINDEX key index
  • LSET

設置指定索引的元素值

LSET key index value
  • LTRIM

只保留列表指定片段,刪除其他元素

LTRIM key start end

其它命令參考官方手冊 : http://redis.io/commands#list

集合類型

集合中的每個元素都不同,且沒有順序。

常用命令如下:

  • SADD

增加一個或多個元素

SADD key member[ member..]
  • SREM

移除一個或多個元素

SREM key member[ member..]
  • SMEMBERS

獲取集合中所有的元素

SMEMBERS key
  • SISMEMBER

判斷元素是否存在集合中

SISMEMBER key member
  • SCARD

獲取集合的元素個數

SCARD key
  • SRANDMEMBER

返回1個或count個隨機元素

SRANDMEMBER key[ count]
  • SDIFF

集合差運算

SDIFF key[ key..]
  • SINTER

集合交集運算

SINTER key[ key..]
  • SUNION

集合並集運算

SUNION key[ key..]

其它sets命令參考官方手冊 : http://redis.io/commands#set

有序集合類型

在集合類型的基礎上有序集合類型爲每個元素都關聯了一個分數,這使我們可以使用集合類型的操作之外,還能做與分數有關的操作。

常用命令如下:

  • ZADD

增加一個帶分數的元素,如果已存在,則替換分數

ZADD key score member[ score member..]
  • ZSCORE

獲得元素分數

ZSCORE key member
  • ZRANGE

獲得排名在某個範圍內的元素,返回按score升序排序的元素

ZRANGE key start end[ WITHSCORES]
  • ZREVRANGE

與zrange使用一致,返回按score降序的元素

ZREVRANGE key start end[ WITHSCORES]
  • ZRANGEBYSCORE

獲得指定分數範圍內的元素

ZRANGEBYSCORE key min max WITHSCORES
  • ZREVRANGEBYSCORE

獲得指定分數範圍內的元素,降序排序

ZREVRANGEBYSCORE key max min WITHSCORES
  • ZINCREBY

增加某個元素的分數

ZINCREBY key increment member
  • ZCARD

獲取集合中元素個數

ZCARD key
  • ZCOUNT

獲得指定分數範圍內的元素個數

ZCOUNT KEY min max
  • ZREM

刪除一個或多個元素

ZREM key member[ member..]
  • ZRANK

獲取分數從小到大排序的位置

ZRANK key member

其它sorted_set命令參考官方手冊 : http://redis.io/commands#sorted_set

redis事務

Redis 事務可以一次執行多個命令,並且帶有以下兩個重要的保證:

  1. 事務是一個單獨的隔離操作:

事務中的所有命令都會序列化、按順序地執行。 事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。

  1. 事務是一個原子操作:

事務中的命令要麼全部被執行,要麼全部都不執行。

一個事務從開始到執行會經歷以下三個階段:

  1. 開始事務(multi)

  2. 命令入隊

  3. 執行事務(exec)

示例如下:

127.0.0.1:6379> MULTIOK127.0.0.1:6379> set var 1QUEUED127.0.0.1:6379> get varQUEUED127.0.0.1:6379> exec1) OK2) "1"
127.0.0.1:6379>

redis客戶端開發庫

c客戶端

Redis官方推薦的C客戶端是hiredis, github地址: https://github.com/redis/hiredis

同步API

  • redisConnect

連接redis數據庫(同步方式)

redisContext *redisConnect(const char *ip, int port);

用法示例:

redisContext *c = redisConnect("127.0.0.1", 6379);if (c == NULL || c->err) {    if (c) {        printf("Error: %s\n", c->errstr);        // handle error
    } else {        printf("Can't allocate redis context\n");
    }
}
  • redisCommand

給redis發送命令

void *redisCommand(redisContext *c, const char *format, ...);

用法示例:

reply = redisCommand(context, "SET foo bar");reply = redisCommand(context, "SET foo %s", value);reply = redisCommand(context, "SET foo %b", value, (size_t)valuelen);reply = redisCommand(context, "SET key:%s %s", myid, value);
  • freeReplyObject

釋放redis資源

void freeReplyObject(void *reply);

其它api參考hiredis.h

異步API

  • redisAsyncConnect

連接redis數據庫(異步方式)

redisAsyncContext *redisAsyncConnect(const char *ip, int port);

示例代碼:

redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);if (c->err) {    printf("Error: %s\n", c->errstr);    // handle error
}
  • redisAsyncSetConnectCallback

redis連接回調函數

int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);

示例代碼:

void connectCallback(const redisAsyncContext *c, int status) {    if (status != REDIS_OK) {        printf("Error: %s\n", c->errstr);        return;
    }    printf("Connected...\n");
}

redisAsyncSetConnectCallback(c,connectCallback);
  • redisAsyncSetDisconnectCallback

redis斷開連接的回調函數

int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);

示例代碼:

void disconnectCallback(const redisAsyncContext *c, int status) {    if (status != REDIS_OK) {        printf("Error: %s\n", c->errstr);        return;
    }    printf("Disconnected...\n");
}

redisAsyncSetDisconnectCallback(c,disconnectCallback);
  • redisAsyncCommand

以異步方式給redis發送命令。

int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);

示例代碼:

void getCallback(redisAsyncContext *c, void *r, void *privdata) {
    redisReply *reply = r;    if (reply == NULL) return;    printf("argv[%s]: %s\n", (char*)privdata, reply->str);    /* Disconnect after receiving the reply to GET */
    redisAsyncDisconnect(c);
}

redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
  • redisAsyncDisconnect

斷開異步連接

void redisAsyncDisconnect(redisAsyncContext *ac);

其它api參考async.h

python客戶端

Redis官方推薦的Python客戶端是redis-py, github地址: https://github.com/andymccurdy/redis-py

安裝方式:

pip install redis

或者

easy_install redis

使用方法

1. 導入redis

import redis

2. 連接到redis

r = redis.StrictRedis() # 默認 127.0.0.1:6379

也可以顯式指定需要連接的地址:

r = redis.StrictRedis(host='127.0.0.1',port=6379,db=0)

3.操作redis

以SET和GET命令爲例:

r.set('var','1')
print r.get('var')

異步方式redis客戶端請參考asyncio_redis: http://asyncio-redis.readthedocs.org/en/latest/

redis作爲消息隊列

工作隊列模式

redis的隊列實際在代碼邏輯中不需要由我們自己實現, 因此一個所謂的 RedisMQ 對象實際是一個 redis key以及對其操作的一些封裝。

可以通過list的lpush和rpop來模擬實現。

127.0.0.1:6379> LPUSH q1 1
(integer) 1
127.0.0.1:6379> LPUSH q1 2
(integer) 2
127.0.0.1:6379> LPUSH q1 3
(integer) 3
127.0.0.1:6379> RPOP q1"1"
127.0.0.1:6379> RPOP q1"2"
127.0.0.1:6379> RPOP q1"3"
127.0.0.1:6379>

如果是優先級隊列可以用zset來實現。

訂閱發佈模式

實現思想很簡單,Publisher調用redis的publish方法往特定的channel發送消息,Subscriber在初始化的時候要subscribe到該channel,一旦有消息就會立即接收。

訂閱消息(redis-cli終端1):

發佈消息(redis-cli終端2):

其它命令參考: http://redis.io/commands#pubsub

更多關於pubsub的描述詳見: http://redis.io/topics/pubsub

Redis作爲消息隊列與RabbitMQ的性能對比:

http://zqdevres.qiniucdn.com/data/20110714104018/index.html

腳本支持

Redis提供了通過eval命令來執行Lua 5.1腳本。

下面通過幾個小例子來講述如何在Redis服務端執行Lua腳本。

  • redis-cli中直接執行lua腳本

  • bash調用redis-cli執行

如果lua腳本內容比較長,可以將lua腳本寫入文件, 然後通過redis-cli執行:

與mysql交互

mysql2redis

https://github.com/dawnbreaks/mysql2redis


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章