redis 總結與應用

url: http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html
url: http://www.infoq.com/cn/articles/tq-why-choose-redis
url: http://www.tuicool.com/articles/ERJFRvy
url: http://blog.nosqlfan.com/html/320.html
url: http://blog.csdn.net/jiangguilong2000/article/details/24143721
url: http://code.google.com/p/redis/wiki/TwitterAlikeExample #做者在wiki中給出了一個很是好的例子,以使咱們能夠快速上手
url: http://labs.alcacoop.it/doku.php?id=articles:redis_land #另外一個redis教程
url: http://www.rediscookbook.org/ #一個redis愛好者建立的相關問題討論網站
url: http://www.infoq.com/cn/articles/tq-why-choose-redis #爲何使用 Redis及其產品定位
url: http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage #Redis內存使用優化與存儲php


1.redis 安裝
下載官網:http://code.google.com/p/redis/downloads/listhtml

2.redis-benchmark 官網:http://code.google.com/p/redis/wiki/Benchmarks
新官網:http://redis.io/mysql

例以下載 redis-2.6.14.tar.gz
命令:tar -xzvf redis-2.6.14.tar.gz
命令:cd redis-2.6.14
命令:make
命令:cd src && make installweb

安裝完畢!
make命令執行完成後,會在當前目錄下生成本個可執行文件,至少有 redis-server、redis-cli、redis-benchmark
redis-server:Redis服務器的daemon啓動程序
redis-cli:Redis命令行操做工具。固然,你也能夠用telnet根據其純文本協議來操做
redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能redis

在安裝包中找到 redis.conf 修改其中的參數:
daemonize: 是否之後臺daemon方式運行
pidfile: pid文件位置
port: 監聽的端口號
timeout: 請求超時時間
loglevel: log信息級別
logfile: log文件位置
databases: 開啓數據庫的數量
save * *: 保存快照的頻率,第一個*表示多長時間,第三個*表示執行多少次寫操做。在必定時間內執行必定數量的寫操做時,自動保存快照。可設置多個條件。
rdbcompression:是否使用壓縮
dbfilename: 數據快照文件名(只是文件名,不包括目錄)
dir: 數據快照的保存目錄(這個是目錄)
appendonly: 是否開啓appendonlylog,開啓的話每次寫操做會記一條log,這會提升數據抗風險能力,但影響效率。
appendfsync:appendonlylog 如何同步到磁盤(三個選項,分別是每次寫都強制調用fsync、每秒啓用一次fsync、不調用fsync等待系統本身同步)
這邊給一份例子(提供參考)
daemonize yes
pidfile /usr/local/redis/var/redis.pid
port 6379
timeout 300
loglevel debug./
logfile /usr/local/redis/var/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /usr/local/redis/var/
appendonly no
appendfsync always
glueoutputbuf yes
shareobjects no
shareobjectspoolsize 1024sql

啓動服務,命令: /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
鏈接到你的redis服務,命令: telnet 127.0.0.1 6379mongodb


3.簡單使用redis (找到 src 文件夾)
命令: ./redis-server ../redis.conf
解釋:啓動redis服務數據庫

命令: ./redis-cli
解釋:另外開一個終端,鏈接redis服務json

命令: (redis>) set name helloword!
解釋:鏈接上redis服務後, 在命令框中輸入數據操做命令; 設置 name 的值爲 "helloword!"服務器

命令: get name
解釋:獲得name的值, 正常狀況獲得 "helloword!"


4.簡單使用 redis benchmark
Redis-benchmark爲Redis性能測試工具
指令說明:
Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]

-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-s <socket> Server socket (overrides host and port)
-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 10000)
-d <size> Data size of SET/GET value in bytes (default 2)
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will get/set keys in the form mykey_rand:000000012456 instead of constant keys, the <keyspacelen> argument determines the max number of values for the random number. For instance if set to 10 only rand:000000000000 - rand:000000000009 range will be allowed.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values 只顯示每秒鐘能處理多少請求數結果
--csv Output in CSV format
-l Loop. Run the tests forever 永久測試
-t <tests> Only run the comma separated list of tests. The test names are the same as the ones produced as output.
-I Idle mode. Just open N idle connections and wait.

實例:
命令: redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100
解釋: SET/GET 100 bytes 檢測host爲127.0.0.1 端口爲6379的redis服務器性能

命令: redis-benchmark -h 127.0.0.1 -p 6379 -c 5000 -n 100000
解釋: 5000個併發鏈接,100000個請求,檢測host爲127.0.0.1 端口爲6379的redis服務器性能

命令: redis-benchmark -n 100000 -c 60
解釋: 向redis服務器發送100000個請求,每一個請求附帶60個併發客戶端

命令: redis-benchmark -h localhost -p 6379 -c 100 -n 100000
解釋: 100個併發鏈接,100000個請求,檢測host爲localhost 端口爲6379的redis服務器性能

命令: redis-cli -h localhost -p 6380 monitor
解釋: Dump all the received requests in real time; 監控host爲localhost,端口爲6380,redis的鏈接及讀寫操做

命令: redis-cli -h localhost -p 6380 info
解釋: Provide information and statistics about the server ; 提供host爲localhost,端口爲6380,redis服務的統計信息


4.redis簡介
redis的代碼遵循ANSI-C編寫,能夠在全部POSIX系統(如Linux,BSD, Mac OS X, Solaris等)上安裝運行。並且Redis並不依賴任何非標準庫,也沒有編譯參數必需添加。redis的安裝出奇的簡單。
redis 由四個可執行文件:redis-benchmark、redis-cli、redis-server、redis-stat?這四個文件,加上一個redis.conf就構成了整個redis的最終可用包。它們的做用以下:
1> redis-server:Redis服務器的daemon啓動程序
2> redis-cli:Redis命令行操做工具。固然,你也能夠用telnet根據其純文本協議來操做
3> redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能
4> redis-stat:Redis狀態檢測工具,能夠檢測Redis當前狀態參數及延遲情況

爲何使用 redis
傳統MySQL + Memcached架構遇到的問題
實際MySQL是適合進行海量數據存儲的,經過Memcached將熱點數據加載到cache,加速訪問,不少公司都曾經使用過這樣的架構,但隨着業務數據量的不斷增長,和訪問量的持續增加,咱們遇到了不少問題:
1.MySQL須要不斷進行拆庫拆表,Memcached也需不斷跟着擴容,擴容和維護工做佔據大量開發時間。
2.Memcached與MySQL數據庫數據一致性問題。
3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL沒法支撐。
4.跨機房cache同步問題。

業界不斷涌現出不少各類各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是咱們須要深刻研究和思考的問題,實際歸根結底最重要的是瞭解這些產品的定位,而且瞭解到每款產品的tradeoffs,在實際應用中作到揚長避短,整體上這些NoSQL主要用於解決如下幾種問題
1.少許數據存儲,高速讀寫訪問。此類產品經過數據所有in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。
2.海量數據存儲,分佈式系統支持,數據一致性保證,方便的集羣節點添加/刪除。
3.這方面最具表明性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個徹底無中心的設計,節點之間經過gossip方式傳遞集羣信息,數據保證最終一致性,後者是一箇中心化的方案設計,經過相似一個分佈式鎖服務來保證強一致性,數據寫入先寫內存和redo log,而後按期compat歸併到磁盤上,將隨機寫優化爲順序寫,提升寫入性能。
4.Schema free,auto-sharding等。好比目前常見的一些文檔數據庫都是支持schema-free的,直接存儲json格式數據,而且支持auto-sharding等功能,好比mongodb。
面對這些不一樣類型的NoSQL產品,咱們須要根據咱們的業務場景選擇最合適的產品。

redis適用場景,如何正確的使用
前面已經分析過,Redis最適合全部數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差異,那麼可能你們就會有疑問,彷佛Redis更像一個增強版的Memcached,那麼什麼時候使用Memcached,什麼時候使用Redis呢?
Redis與Memcached的比較
1.網絡IO模型
Memcached是多線程,非阻塞IO複用的網絡模型,分爲監聽主線程和worker子線程,監聽線程監聽網絡鏈接,接受請求後,將鏈接描述字pipe 傳遞給worker線程,進行讀寫IO, 網絡層使用libevent封裝的事件庫,多線程模型能夠發揮多核做用,可是引入了cache coherency和鎖的問題,好比,Memcached最經常使用的stats 命令,實際Memcached全部操做都要對這個全局變量加鎖,進行計數等工做,帶來了性能損耗。
Redis 使用單線程的IO複用模型,本身封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操做來講,單線程能夠將速度優點發揮到最大,可是Redis也提供了一些簡單的計算功能,好比排序、聚合等,對於這些操做,單線程模型實際會嚴重影響總體吞吐量,CPU計算過程當中,整個IO調度都是被阻塞住的。

2.內存管理方面
Memcached使用預分配的內存池的方式,使用slab和大小不一樣的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內存池的方式能夠省去申請/釋放內存的開銷,而且能減少內存碎片產生,但這種方式也會帶來必定程度上的空間浪費,而且在內存仍然有很大空間時,新的數據也可能會被剔除,緣由能夠參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/
Redis使用現場申請內存的方式來存儲數據,而且不多使用free-list等方式來優化內存分配,會在必定程度上存在內存碎片,Redis跟據存儲命令參數,會把帶過時時間的數據單獨存放在一塊兒,並把它們稱爲臨時數據,非臨時數據是永遠不會被剔除的,即使物理內存不夠,致使swap也不會剔除任何非臨時數據(但會嘗試剔除部分臨時數據),這點上Redis更適合做爲存儲而不是cache。

3.數據一致性問題
Memcached提供了cas命令,能夠保證多個併發訪問操做同一份數據的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,能夠保證一串 命令的原子性,中間不會被任何操做打斷。

4.存儲方式及其它方面
Memcached基本只支持簡單的key-value存儲,不支持枚舉,不支持持久化和複製等功能
Redis除key/value以外,還支持list,set,sorted set,hash等衆多數據結構,提供了KEYS進行枚舉操做,但不能在線上使用,若是須要枚舉線上數據,Redis提供了工具能夠直接掃描其dump文件,枚舉出全部數據,Redis還同時提供了持久化和複製等功能。

5.關於不一樣語言的客戶端支持
在不一樣語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過由於Memcached發展的時間更久一些,目前看在客戶端支持方面,Memcached的不少客戶端更加成熟穩定,而Redis因爲其協議自己就比Memcached複雜,加上做者不斷增長新的功能等,對應第三方客戶端跟進速度可能會趕不上,有時可能須要本身在第三方客戶端基礎上作些修改才能更好的使用。根據以上比較不難看出,當咱們不但願數據被踢出,或者須要除key/value以外的更多數據類型時,或者須要落地功能時,使用Redis比使用Memcached更合適。

關於Redis的一些周邊功能
Redis除了做爲存儲以外還提供了一些其它方面的功能,好比聚合計算、pubsub、scripting等,對於此類功能須要瞭解其實現原理,清楚地瞭解到它的侷限性後,才能正確的使用,好比pubsub功能,這個實際是沒有任何持久化支持的,消費方鏈接閃斷或重連之間過來的消息是會所有丟失的,又好比聚合計算和scripting等功能受Redis單線程模型所限,是不可能達到很高的吞吐量的,須要謹慎使用。總的來講Redis做者是一位很是勤奮的開發者,能夠常常看到做者在嘗試着各類不一樣的新鮮想法和思路,針對這些方面的功能就要求咱們須要深刻了解後再使用。

總結:
1.Redis使用最佳方式是所有數據in-memory。
2.Redis更多場景是做爲Memcached的替代者來使用。
3.當須要除key/value以外的更多數據類型支持時,使用Redis更合適。
當存儲的數據不能被剔除時,使用Redis更合適。

關於做者
田琪,目前負責新浪微博平臺底層架構與研發工做,以前曾擔任搜狐白社會實時遊戲平臺核心架構工做,主要關注webgame, 分佈式存儲,nosql 和 erlang 等領域,目前主要從事mysql源代碼的一些深刻研究工做,浪微博:?http://weibo.com/bachmozart。

附:redis命令列表: 鏈接控制 QUIT 關閉鏈接 AUTH (僅限啓用時)簡單的密碼驗證 適合全體類型的命令 EXISTS key 判斷一個鍵是否存在;存在返回 1;不然返回0; DEL key 刪除某個key,或是一系列key;DEL key1 key2 key3 key4 TYPE key 返回某個key元素的數據類型( none:不存在,string:字符,list,set,zset,hash) KEYS pattern 返回匹配的key列表(KEYS foo*:查找foo開頭的keys) RANDOMKEY 隨機得到一個已經存在的key,若是當前數據庫爲空,則返回空字符串 RENAME oldnamenewname 更改key的名字,新鍵若是存在將被覆蓋 RENAMENX oldnamenewname 更改key的名字,若是名字存在則更改失敗 DBSIZE 返回當前數據庫的key的總數 EXPIRE 設置某個key的過時時間(秒),(EXPIRE bruce1000:設置bruce這個key1000秒後系統自動刪除)注意:若是在尚未過時的時候,對值進行了改變,那麼那個值會被清除。 TTL 查找某個key還有多長時間過時,返回時間秒 SELECT index 選擇數據庫 MOVE key dbindex 將指定鍵從當前數據庫移到目標數據庫 dbindex。成功返回1;不然返回0(源數據庫不存在key或目標數據庫已存在同名key); FLUSHDB 清空當前數據庫中的全部鍵 FLUSHALL 清空全部數據庫中的全部鍵 處理字符串的命令 SET key value 給一個鍵設置字符串值。SET keyname datalength data (SET bruce 10paitoubing:保存key爲burce,字符串長度爲10的一個字符串paitoubing到數據庫),data最大不可超過1G。 GET key 獲取某個key的value值。如key不存在,則返回字符串「nil」;如key的值不爲字符串類型,則返回一個錯誤。 GETSET keyvalue 能夠理解成得到的key的值而後SET這個值,更加方便的操做 (SET bruce 10paitoubing,這個時候須要修改bruce變成1234567890並獲取這個之前的數據paitoubing,GETSETbruce 10 1234567890) MGET key1 key2 … keyN 一次性返回多個鍵的值 SETNX key value SETNX與SET的區別是SET能夠建立與更新key的value,而SETNX是若是key不存在,則建立key與value數據 MSET key1 value1 key2value2 … keyN valueN 在一次原子操做下一次性設置多個鍵和值 MSETNX key1 value1 key2value2 … keyN valueN 在一次原子操做下一次性設置多個鍵和值(目標鍵不存在狀況下,若是有一個以上的key已存在,則失敗) INCR key 自增鍵值 INCRBY key integer 令鍵值自增指定數值 DECR key 自減鍵值 DECRBY key integer 令鍵值自減指定數值 處理 lists 的命令 RPUSH key value 從 List尾部添加一個元素(如序列不存在,則先建立,如已存在同名Key而非序列,則返回錯誤) LPUSH key value 從 List頭部添加一個元素 LLEN key 返回一個 List的長度 LRANGE key startend 從自定的範圍內返回序列的元素 (LRANGE testlist 0 2;返回序列testlist前0 1 2元素) LTRIM key startend 修剪某個範圍以外的數據 (LTRIM testlist 0 2;保留0 1 2元素,其他的刪除) LINDEX keyindex 返回某個位置的序列值(LINDEX testlist 0;返回序列testlist位置爲0的元素) LSET key indexvalue 更新某個位置元素的值 LREM key count value 從List的頭部(count正數)或尾部(count負數)刪除必定數量(count)匹配value的元素,返回刪除的元素數量。 LPOP key 彈出 List的第一個元素 RPOP key 彈出 List的最後一個元素 RPOPLPUSH srckey dstkey 彈出 _srckey_ 中最後一個元素並將其壓入 _dstkey_頭部,key不存在或序列爲空則返回「nil」 處理集合(sets)的命令(有索引無序序列) SADD keymember 增長元素到SETS序列,若是元素(membe)不存在則添加成功 1,不然失敗 0;(SADD testlist 3 \none) SREM key member 刪除SETS序列的某個元素,若是元素不存在則失敗0,不然成功 1(SREM testlist 3 \N one) SPOP key 從集合中隨機彈出一個成員 SMOVE srckey dstkeymember 把一個SETS序列的某個元素 移動到 另一個SETS序列 (SMOVE testlist test 3\ntwo;從序列testlist移動元素two到 test中,testlist中將不存在two元素) SCARD key 統計某個SETS的序列的元素數量 SISMEMBER key member 獲知指定成員是否存在於集合中 SINTER key1 key2 … keyN 返回 key1, key2, …, keyN 中的交集 SINTERSTORE dstkey key1key2 … keyN 將 key1, key2, …, keyN 中的交集存入 dstkey SUNION key1 key2 … keyN 返回 key1, key2, …, keyN 的並集 SUNIONSTORE dstkey key1key2 … keyN 將 key1, key2, …, keyN 的並集存入 dstkey SDIFF key1 key2 … keyN 依據 key2, …, keyN 求 key1 的差集。官方例子: key1 = x,a,b,c key2 = c key3 = a,d SDIFF key1,key2,key3=> x,b SDIFFSTORE dstkey key1key2 … keyN 依據 key2, …, keyN 求 key1 的差集並存入 dstkey SMEMBERS key 返回某個序列的全部元素 SRANDMEMBER key 隨機返回某個序列的元素 處理有序集合(sorted sets)的命令 (zsets) ZADD key score member 添加指定成員到有序集合中,若是目標存在則更新score(分值,排序用) ZREM key member 從有序集合刪除指定成員 ZINCRBY key incrementmember 若是成員存在則將其增長_increment_,不然將設置一個score爲_increment_的成員 ZRANGE key start end 返回升序排序後的指定範圍的成員 ZREVRANGE key start end 返回降序排序後的指定範圍的成員 ZRANGEBYSCORE key minmax 返回全部符合score >= min和score <=max的成員 ZCARD key 返回有序集合的元素數量 ZSCORE key element 返回指定成員的SCORE值ZREMRANGEBYSCORE key min max 刪除符合 score >= min 和score <= max 條件的全部成員 排序(List, Set, Sorted Set) SORT key BY patternLIMIT start end GET pattern ASC|DESC ALPHA 按照指定模式排序集合或List SORT mylist 默認升序 ASC SORT mylist DESC SORT mylist LIMIT 0 10 從序號0開始,取10條 SORT mylist LIMIT 0 10 ALPHA DESC 按首字符排序 SORT mylist BYweight_* SORT mylist BY weight_* GET object_* SORT mylist BY weight_* GET object_* GET SORT mylist BY weight_*STORE resultkey 將返回的結果存放於resultkey序列(List) 持久控制 SAVE 同步保存數據到磁盤 BGSAVE 異步保存數據到磁盤 LASTSAVE 返回上次成功保存到磁盤的Unix時間戳 SHUTDOWN 同步保存到服務器並關閉Redis 服務器(SAVE+QUIT) BGREWRITEAOF 當日志文件過長時重寫日誌文件 遠程控制命令 INFO 提供服務器的信息和統計信息 MONITOR 實時輸出全部收到的請求 SLAVEOF 修改複製選項

相關文章
相關標籤/搜索