一、Redis概述 1.1、什麼是Redis Redis是一種高級key-value數據庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字符串,鏈表,集 合和有序集合。支持在服務器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis也可以被看成是一個數據結構服務 器。 Redis的所有數據都是保存在內存中,然後不定期的通過異步方式保存到磁盤上(這稱爲“半持久化模式”);也可以把每一次數據變化都寫入到一個append only file(aof)裏面(這稱爲“全持久化模式”)。 1.2、Redis數據持久化(俗稱“數據落地”) 第一種方法filesnapshotting:默認redis是會以快照的形式將數據持久化到磁盤的(一個二進制文 件,dump.rdb,這個文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之內,redis至少發生M次修改則redis抓快照到磁盤。當然我們也可以手動執行save或者bgsave(異步)做快照。 工作原理簡單介紹一下:當redis需要做持久化時,redis會fork一個子進程;子進程將數據寫到磁盤上一個臨時RDB文件中;當子進程完成寫臨時文件後,將原來的RDB替換掉,這樣的好處就是可以copy-on-write 還有一種持久化方法是Append-only:filesnapshotting方法在redis異常死掉時, 最近的數據會丟失(丟失數據的多少視你save策略的配置),所以這是它最大的缺點,當業務量很大時,丟失的數據是很多的。Append-only方法可 以做到全部數據不丟失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中開啓(默認是no),appendonly yes開啓AOF之後,redis每執行一個修改數據的命令,都會把它添加到aof文件中,當redis重啓時,將會讀取AOF文件進行“重放”以恢復到 redis關閉前的最後時刻. LOG Rewriting隨着修改數據的執行AOF文件會越來越大,其中很多內容記錄某一個key的變化情況。因此redis有了一種比較有意思的特性:在後臺重建AOF文件,而不會影響client端操作。在任何時候執行BGREWRITEAOF命令,都會把當前內存中最短序列的命令寫到磁盤,這些命令可以完全構建當前的數據情況,而不會存在多餘的變化情況(比如狀態變化,計數器變化等),縮小的AOF文件的大小。所以當使用AOF時,redis推薦同時使用BGREWRITEAOF. 二、Redis安裝 2.1、redis安裝 # cd /data/soft/ # tar xf redis-2.4.15.tar.gz -C tmp/ # cd tmp/redis-2.4.15/ #make PREFIX=/usr/local/services/redis-2.4.15 >/dev/null #make PREFIX=/usr/local/services/redis-2.4.15 install >/dev/null #ln -s /usr/local/services/redis-2.4.15/bin/ /usr/local/services/redis/ 會在當前目錄下生成本個可執行文件,分別是redis-server、redis-cli、redis-benchmark、redis-stat,它們的作用如下: redis-server:Redis服務器的daemon啓動程序 redis-cli:Redis命令行操作工具。當然,你也可以用telnet根據其純文本協議來操作 redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能 redis-stat:Redis狀態檢測工具,可以檢測Redis當前狀態參數及延遲狀況 2.2、調整overcommit_memory參數 如果內存情況比較緊張的話,需要設定內核參數overcommit_memory,指定內核針對內存分配的策略,其值可以是0、1、2。 0,表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。 1,表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。 2,表示內核允許分配超過所有物理內存和交換空間總和的內存 Redis在dump數據的時候,會fork出一個子進程,理論上child進程所佔用的內存和parent是一樣的,比如parent佔用的內存爲 8G,這個時候也要同樣分配8G的內存給child, 如果內存無法負擔,往往會造成redis服務器的down機或者IO負載過高,效率下降。所以這裏比較優化的內存分配策略應該設置爲 1(表示內核允許分配所有的物理內存,而不管當前的內存狀態如何)。 設置方式有兩種,需確定當前用戶的權限活使用root用戶修改: 1:重設文件 # echo 1 > /proc/sys/vm/overcommit_memory(默認爲0) 2: # echo "vm.overcommit_memory=1" >> /etc/sysctl.conf # /sbin/sysctl -p 2.3、拷貝配置文件 #mkdir /usr/local/services/redis-2.4.15/etc # cd /soft/redis/redis-2.4.15 # cp redis.conf /usr/local/services/redis-2.4.15/etc/ 2.4、redis配置文件 # mkdir –p /data/redis/redis_db #mkdir –p /data/redis/redis_dump daemonize yes pidfile /data/redis/redis_db/redis.pid port 6379 timeout 300 loglevel debug logfile stdout databases 16 save 900 1 save 300 10 save 60 10000 rdbcompression yes dbfilename dump.rdb dir /data/redis/redis_dump slave-serve-stale-data yes appendonly no appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb slowlog-log-slower-than 10000 slowlog-max-len 128 vm-enabled no vm-swap-file /data/redis/redis_db/redis.swap vm-max-memory 0 vm-page-size 32 vm-pages 134217728 vm-max-threads 4 hash-max-zipmap-entries 512 hash-max-zipmap-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 activerehashing yes bind 127.0.0.1 配置文件說明 daemonize yes # Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啓用守護進程 pidfile /data/redis/redis_db/redis.pid #當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,可以通過pidfile指定 port 6379 #指定Redis監聽端口,默認端口爲6379,作者在自己的一篇博文中解釋了爲什麼選用6379作爲默認端口,因爲6379在手機按鍵上MERZ對應的號碼,而MERZ取自意大利歌女Alessia Merz的名字 timeout 300 #當客戶端閒置多長時間後關閉連接,如果指定爲0,表示關閉該功能 loglevel debug #指定日誌記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認爲verbose logfile stdout #日誌記錄方式,默認爲標準輸出,如果配置Redis爲守護進程方式運行,而這裏又配置爲日誌記錄方式爲標準輸出,則日誌將會發送給/dev/null databases 16 #設置數據庫的數量,默認數據庫爲0,可以使用SELECT <dbid>命令在連接上指定數據庫id #指定在多長時間內,有多少次更新操作,就將數據同步到數據文件,可以多個條件配合 Redis默認配置文件中提供了三個條件 save 900 1 save 300 10 save 60 10000 #指定存儲至本地數據庫時是否壓縮數據,默認爲yes,Redis採用LZF壓縮,如果爲了節省CPU時間,可以關閉該選項,但會導致數據庫文件變的巨大 rdbcompression yes #指定本地數據庫文件名,默認值爲dump.rdb dbfilename dump.rdb #指定本地數據庫存放目錄 dir /data/redis/redis_dump 設置當本機爲slav服務時,設置master服務的IP地址及端口,在Redis啓動時,它會自動從master進行數據同步 slave-serve-stale-data yes . 指定是否在每次更新操作後進行日誌記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啓,可能會在斷電時導致一段時間內的數據丟失。因爲 redis本身同步數據文件是按上面save條件來同步的,所以有的數據會在一段時間內只存在於內存中。默認爲no appendonly no 指定更新日誌條件,共有3個可選值: no:表示等操作系統進行數據緩存同步到磁盤(快) always:表示每次更新操作後手動調用fsync()將數據寫到磁盤(慢,安全) everysec:表示每秒同步一次(折衷,默認值) appendfsync everysec 當AOF文件增長到一定大小的時候Redis能夠調用 BGREWRITEAOF 對日誌文件進行重寫 no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 注意制定一個負數將關閉慢日誌,而設置爲0將強制每個命令都會記錄 slowlog-log-slower-than 10000 slowlog-max-len 128 指定是否啓用虛擬內存機制,默認值爲no,簡單的介紹一下,VM機制將數據分頁存放,由Redis將訪問量較少的頁即冷數據swap到磁盤上,訪問多的頁面由磁盤自動換出到內存中(在後面的文章我會仔細分析Redis的VM機制) vm-enabled no 虛擬內存文件路徑,默認值爲/tmp/redis.swap,不可多個Redis實例共享 vm-swap-file /data/redis/redis_db/redis.swap #交換文件 將所有大於vm-max-memory的數據存入虛擬內存,無論vm-max-memory設置多小,所有索引數據都是內存存儲的(Redis的索引數據 就是keys),也就是說,當vm-max-memory設置爲0的時候,其實是所有value都存在於磁盤。默認值爲0 vm-max-memory 0 Redis swap文件分成了很多的page,一個對象可以保存在多個page上面,但一個page上不能被多個對象共享,vm-page-size是要根據存儲的 數據大小來設定的,作者建議如果存儲很多小對象,page大小最好設置爲32或者64bytes;如果存儲很大大對象,則可以使用更大的page,如果不 確定,就使用默認值 vm-page-size 32 設置swap文件中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在內存中的,,在磁盤上每8個pages將消耗1byte的內存 vm-pages 134217728 設置訪問swap文件的線程數,最好不要超過機器的核數,如果設置爲0,那麼所有對swap文件的操作都是串行的,可能會造成比較長時間的延遲。默認值爲4 vm-max-threads 4 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的哈希算法 hash-max-zipmap-entries 512 hash-max-zipmap-value 64 list數據類型節點值大小小於多少字節會採用緊湊存儲格式。 list-max-ziplist-entries 512 list-max-ziplist-value 64 set數據類型內部數據如果全部是數值型,且包含多少節點以下會採用緊湊格式存儲。 set-max-intset-entries 512 zsort數據類型節點值大小小於多少字節會採用緊湊存儲格式。 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 指定是否激活重置哈希,默認爲開啓 activerehashing yes 綁定的主機地址 bind 127.0.0.1 2.5、啓動Redis服務 # redis-server conf/redis.conf # redis-cli shutdown 停止Redis 關閉服務 # redis-cli -p 6380 shutdown 如果非默認端口,可指定端口: 2.6、測試Redis # ls /data/redis/redis_dump/ 看看是否有文件。沒有?正常。我們寫入數據進去 # telnet localhost 6379 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get mykey $-1 set foo 3 +OK get foo $1 3 quit +OK Connection closed by foreign host. # ls /data/redis/redis_dump/ 在此嘗試看看。。
Redis
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.