1. 程式人生 > 實用技巧 >Redis學習之路(二)之Redis入門基礎

Redis學習之路(二)之Redis入門基礎

Redis學習之路(二)之Redis入門基礎

  • 一、Redis基本介紹

  • (1)Redis介紹

  Redis 是一個開源(BSD許可)的,記憶體中的資料結構儲存系統,它可以用作資料庫、快取和訊息中介軟體. 它支援多種型別的資料結構,如 字串(strings), 雜湊(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢,` bitmaps,hyperloglogs 和 地理空間(geospatial) 索引半徑查詢.Redis 內建了 複製(replication), LUA指令碼(Lua scripting), LRU驅動事件(LRU eviction), 事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過Redis哨兵(Sentinel) 和自動分割槽(Cluster)提供高可用性(high availability)。

    可以對這些型別執行 原子操作 , 列如: 字串(strings)的append 命令; 雜湊(hashes)的hincrby命令; 列表(lists)的lpush命令; 集合(sets)計算交集sinter命令, 計算並集union命令 和 計算差集sdiff命令; 或者 在有序集合(sorted sets)裡面獲取成員的最高排名zrangebyscore命令。

    為了實現其卓越的效能, Redis採用執行在 記憶體中的資料集工作方式. 根據使用情況, 可以每隔一定時間將 資料集匯出到磁碟 , 或者 追加到命令日誌中. 也可以關閉持久化功能,將Redis作為一個高效的網路的快取資料功能使用.

    Redis 同樣支援 主從複製(能自動重連和網路斷開時自動重新同步),並且第一次同步是快速的非阻塞式的同步.
  其他功能包括:
(1)事務(Transactions)
(2)訂閱分發(Pub/Sub)
(3)LUA指令碼(Lua scripting)
(4)過期自動刪除key
(5)記憶體回收
(6)自動故障轉移

  • (2)Redis特點

1)支援記憶體快取,這個功能相當於memcached

2)支援持久化儲存,這個功能相當於memcachedb,ttserver

3)資料庫型別更豐富。比其他key-value庫功能更強

4)支援主從叢集、分散式

5)支援佇列等特殊功能

  • (3)Redis和Memecache的區別

1.儲存方式:
memecache 把資料全部存在記憶體之中,斷電後會掛掉,資料不能超過記憶體大小, Redis有部份存在硬碟上,這樣能保證資料的永續性,支援資料的持久化。

2.資料支援型別:
redis在資料支援上要比memecache多的多。

3.使用底層模型不同
新版本的redis直接自己構建了VM 機制,因為一般的系統呼叫系統函式的話,會浪費一定的時間去移動和請求。

總結:對於兩者的選擇還是要看具體的應用場景,如果需要快取的資料只是key-value這樣簡單的結構時,我在專案裡還是採用memcache,它也足夠的穩定可靠。如果涉及到儲存,排序等一系列複雜的操作時,毫無疑問選擇redis。

  • 二、Redis部署

redis下載地址:http://www.redis.cn/download.html

  • 1、安裝–>下載,解壓,編譯

(1)下載、解壓、編譯
[root@redis ~]# wget http://download.redis.io/releases/redis-4.0.9.tar.gz
[root@redis ~]# tar xzf redis-4.0.9.tar.gz -C /usr/local/
[root@redis redis-4.0.9]# cd /usr/local/redis-4.0.9
[root@redis redis-4.0.9]# make
[root@redis redis-4.0.9]# make install

(2)建立軟連結
[root@redis redis-4.0.9]# ln -sv /usr/local/redis-4.0.9 /usr/local/redis
"/usr/local/redis" -> "/usr/local/redis-4.0.9"
[root@redis redis-4.0.9]# ll /usr/local/redis*
lrwxrwxrwx 1 root root   22 5月  18 10:53 /usr/local/redis -> /usr/local/redis-4.0.9

(3)修改redis配置檔案redis.conf
[root@redis ~]# vim /usr/local/redis/redis.conf 
bind 127.0.0.1   #監聽的ip地址
port 6379        #埠
daemonize yes    #開啟後臺執行模式
pidfile /var/run/redis_6379.pid   #pid路徑
logfile "/var/log/redis.log"      #日誌路徑
dir /data/redis_data              #資料儲存路徑
  • 2、啟動redis

(1)編寫redis啟動指令碼
[root@redis ~]# vim /usr/lib/systemd/system/redis.service 
[Unit]
Description=Redis
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/redis_6379.pid
ExecStart=/usr/local/redis/src/redis-server /usr/local/redis/redis.conf 
ExecReload=/bin/kill -s HUP $MAINPID 
ExecStop=/bin/kill -s QUIT $MAINPID 
PrivateTmp=true

[Install]
WantedBy=multi-user.target

(2)啟動redis
[root@redis ~]# systemctl daemon-reload
[root@redis ~]# systemctl start redis
[root@redis ~]# ps -ef |grep redis
root     31615     1  0 11:48 ?        00:00:00 /usr/local/redis/src/redis-server 127.0.0.1:6379
root     31620 31352  0 11:48 pts/1    00:00:00 grep --color=auto redis
[root@redis ~]# netstat -tulnp |grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      31615/redis-server  
[root@redis ~]# redis-cli 
127.0.0.1:6379> KEYS *
1) "k1"
  • 3、redis常見操作
keys *    //取出所有key
keys my* //模糊匹配
exists name  //有name鍵 返回1 ,否則返回0;
del  key1 // 刪除一個key    //成功返回1 ,否則返回0;
EXPIRE key1 100  //設定key1 100s後過期
ttl key // 檢視鍵 還有多長時間過期,單位是s,當 key 不存在時,返回 -2 。 當 key 存在但沒有設定剩餘生存時間時,返回 -1 。 否則,返回 key 的剩餘生存時間。
select  0  //代表選擇當前資料庫,預設進入0 資料庫
move age 1  // 把age 移動到1 資料庫
persist key1   //取消key1的過期時間
randomkey //隨機返回一個key
rename oldname newname //重新命名key
type key1 //返回鍵的型別
dbsize  //返回當前資料庫中key的數目
info  //返回redis資料庫狀態資訊
flushdb //清空當前資料庫中所有的鍵
flushall    //清空所有資料庫中的所有的key
bgsave //儲存資料到 rdb檔案中,在後臺執行
save //作用同上,但是在前臺執行
config get * //獲取所有配置引數
config get dir  //獲取配置引數
config set dir  //更改配置引數
資料恢復: 首先定義或者確定dir目錄和dbfilename,然後把備份的rdb檔案放到dir目錄下面,重啟redis服務即可恢復資料
  • 4、redis.conf詳解
[root@redis ~]# grep "^[a-Z]" /usr/local/redis/redis.conf 
bind 127.0.0.1          #繫結監聽的ip地址,可以有多個監聽地址,如外網需要連線,設定0.0.0.0 空格分隔
protected-mode yes      #是否開啟保護模式,當redis.conf中沒有定義bind的ip時,也就是說redis將會繫結全網IP, 並且也沒有設定訪問密碼,這兩個條件滿足時,當遠端的機器訪問redis時,就會被限制了。建議開啟。
port 6379               #監聽埠
tcp-backlog 511         #關於backlog的理解,需要先搞清楚TCP三次握手。這個tcp-backlog定義了一個佇列的長度。這個佇列指的是, TCP三次握手中最後一次握手完成後的那個狀態的連線,該引數設定的值不能大於核心的somaxconn的值,要想設定的非常高,那麼首先要將核心引數somaxconn的值提升。 somaxconn,定義了系統中每一個埠最大的監聽佇列的長度,這是個全域性的引數,預設值為128. 限制了每個埠接收新tcp連線偵聽佇列的大小。對於一個經常處理新連線的高負載 web服務環境來說,預設的128太小了。 大多數環境這個值建議增加到2048或者更多。調整核心引數: echo "net.core.somaxconn = 2048" >> /etc/sysctl.conf; sysctl -p
timeout 0               # 當客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能
tcp-keepalive 300       # TCP長連線保持時長。單位為秒,假如設定為60秒,則server端會每60秒向連線空閒的客戶端發起一次ACK請求, 以檢查客戶端是否已經掛掉,對於無響應的客戶端則會關閉其連線。所以關閉一個連線最長需要120秒的時間。如果設定為0,則不會進行保活檢測。
daemonize yes           #Redis預設不是以守護程序的方式執行,可以通過該配置項修改,使用yes啟用守護程序
                        #啟用守護程序後,Redis會把pid寫到一個pidfile中,在/var/run/redis_6379.pid
supervised no       #是否通過upstart或systemd管理守護程序。預設no沒有服務監控,其它選項有upstart, systemd, auto
pidfile /var/run/redis_6379.pid     #pid檔案路徑
loglevel notice     # 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning
logfile "/var/log/redis.log"    #指定日誌檔案路徑
databases 16        # 設定資料庫的數量,預設資料庫為0,可以使用select <dbid>命令在連線上指定資料庫id
always-show-logo yes   #redis啟動時,會列印ASCII藝術logo

################################ SNAPSHOTTING(快照備份) ################################# # 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合 # 滿足以下條件將會同步資料: # 900秒(15分鐘)內有1個更改 # 300秒(5分鐘)內有10個更改 # 60秒內有10000個更改 # Note: 可以把所有“save”行註釋掉,這樣就取消同步操作了 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes   #當save過程中出現失敗的情況時,或者有某些錯誤時,總之導致了記憶體中的資料和磁碟中的資料不一致了。該引數定義此時是否繼續進行save的操作。 rdbcompression yes # 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮 # 如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大 rdbchecksum yes # 當save完成後,是否使用CRC64演算法校驗rdb檔案。 dbfilename dump.rdb # 指定本地資料庫檔名,預設值為dump.rdb dir /data/redis_data #資料庫(dump.rdb)檔案存放目錄,注意,這裡只能指定一個目錄,不能指定檔名 ################################# REPLICATION(主從複製) ################################# # 主從複製。使用slaveof從 Redis伺服器複製一個Redis例項。注意,該配置僅限於當前slave有效 # 設定當本機為slav服務時,設定master服務的ip地址及埠,在Redis啟動時,它會自動從master進行資料同步 # 當master服務設定了密碼保護時,slave服務連線master的密碼 slaveof <masterip> <masterport> #主從複製使用,用於本機redis作為slave去連線主redis,配置主redis的ip和埠
masterauth <master-password> #當master設定密碼認證,slave用此選項指定master認證密碼
slave-serve-stale-data yes #當slave與master之間的連線斷開或slave正在與master進行資料同步時, 如果有slave請求,當設定為yes時,slave仍然響應請求,此時可能有問題, 如果設定no時,slave會返回"SYNC with master in progress"錯誤資訊。 但INFO和SLAVEOF命令除外。
slave-read-only yes #在從上配置,開啟從只讀模式,無法在從上進行寫入操作
repl-diskless-sync no #是否開啟主從複製的磁碟同步,預設為no。定義主從同步資料的策略,它有兩種策略,一個是磁碟形式,一個是socket(就是這個diskless)形式。 磁碟形式,就是先將資料寫到rdb檔案裡,然後傳輸rdb檔案到從上。 socket形式,就是直接通過網路傳輸變更的資料到從上的rdb檔案裡。 repl-diskless-sync no,表示使用磁碟的形式。
repl-diskless-sync-delay 5 #磁碟同步的時延。如果使用了通過socket的形式傳輸資料,則需要考慮一個主下面有多個從的情況,因為一旦基於Diskless的複製傳送開始, 主就無法顧及新的從的到來。所以,就有了這個延遲的設定,比如延遲5秒,這樣在主從傳輸資料之前,所有的從都被識別了, 這樣主就可以多開幾個執行緒來同時給所有的從進行資料傳輸了。
repl-disable-tcp-nodelay no #是否開啟tcp時延。是否關閉tcp_nodelay功能。 關於tcp_nodelay有個nagle演算法,假如需要頻繁的傳送一些小包資料,比如說1個位元組,以IPv4為例的話, 則每個包都要附帶40位元組的頭,也就是說,總計41個位元組的資料裡,其中只有1個位元組是我們需要的資料。為了解決這個問題,出現了Nagle演算法。 它規定:如果包的大小滿足MSS,那麼可以立即傳送,否則資料會被放到緩衝區,等到已經發送的包被確認了之後才能繼續傳送。 通過這樣的規定,可以降低網路裡小包的數量,從而提升網路效能。該引數設定為no,即使用tcp_nodelay,資料傳輸到salve的延遲將會減少但要使用更多的頻寬。 反之,不使用tcp_nodelay,這樣Redis主將使用更少的TCP包和頻寬來向slaves傳送資料。 但是這將使資料傳輸到slave上有延遲,Linux核心的預設配置會達到40毫秒。

repl-backlog-size 1mb  #首先解釋一下,這裡的backlog是主上的一個記憶體緩衝區,它儲存的資料是當主和從斷開連線時,主無法將資料傳給從了,這時候主先將更新的資料 暫時存放在快取去裡。如果主從再次連線時,就不需要重新傳輸所有資料,而是隻需要傳輸緩衝區的這一部分即可。這個引數用來定義該緩衝區的大小。

repl-backlog-ttl 3600  #如果主Redis等了一段時間之後,還是無法連線到從Redis,那麼緩衝佇列中的資料將被清理掉。我們可以設定主Redis要等待的時間長度。 如果設定為0,則表示永遠不清理。預設是1個小時。

replica-priority 100  #我們可以給眾多的從Redis設定優先順序,在主Redis持續工作不正常的情況,優先順序高的從Redis將會升級為主Redis。而編號越小,優先順序越高。 比如一個主Redis有三個從Redis,優先順序編號分別為10、100、25,那麼編號為10的從Redis將會被首先選中升級為主Redis。 當優先順序被設定為0時,這個從Redis將永遠也不會被選中。預設的優先順序為100。

min-replicas-to-write 3 /min-replicas-max-lag 10  #假如主Redis發現有超過M個從Redis的連線延時大於N秒,那麼主Redis就停止接受外來的寫請求。這是因為從Redis一般會每秒鐘都向主Redis發出PING, 而主Redis會記錄每一個從Redis最近一次發來PING的時間點,所以主Redis能夠了解每一個從Redis的執行情況。

min-replicas-to-write 3 /min-replicas-max-lag 10  #表示,假如有大於等於3個從Redis的連線延遲大於10秒,那麼主Redis就不再接受外部的寫請求。 上述兩個配置中有一個被置為0,則這個特性將被關閉。預設情況下min-slaves-to-write為0,而min-slaves-max-lag為10。

slave-priority 100 # 從的權重設定

############################ 安全配置 ##################################### requirepass foobared # 設定Redis連線密碼 #如果配置了連線密碼,客戶端在連線Redis時需要通過auth <password>命令提供密碼,預設關閉

rename-command CONFIG ""   #限制CONFIG命令使用,當redis被入侵時,為了避免CONFIG命令的危險性,可以對CONFIG命令進行配置不允許使用CONFIG命令。 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no slave-lazy-flush no #是否開啟從上的懶重新整理,預設關閉 ############################## LIMIT(限制) ############################### maxclients 128 #允許設定客戶端最大連線數,0為不限制 maxmemory <bytes> #記憶體清理策略,如果達到此值,將採取以下動作: # volatile-lru :預設策略,只對設定過期時間的key進行LRU演算法刪除 # allkeys-lru :刪除不經常使用的key # volatile-random :隨機刪除即將過期的key # allkeys-random :隨機刪除一個key # volatile-ttl :刪除即將過期的key # noeviction :不過期,寫操作返回報錯 maxmemory-policy volatile-lru #如果達到maxmemory值,採用此策略 maxmemory-samples 3 #預設隨機選擇3個key,從中淘汰最不經常用的 ############################## APPEND ONLY MODE ############################### appendonly no #yes表示開啟aof持久化。指定是否在每次更新操作後進行日誌記錄, #Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。 # 因為redis本身同步資料檔案是按上面save條件來同步的, # 所以有的資料會在一段時間內只存在於記憶體中。預設為no
appendfilename "appendonly.aof" # 指定更新日誌檔名,預設為appendonly.aof
appendfsync everysec # 指定更新日誌條件,共有3個可選值: # no:不呼叫fsync()函式,而是讓作業系統自行決定sync的時間,這種模式下,redis的效能會最快。 # always:在每次寫請求後都呼叫fsync()函式,這種模式下,redis相對會較慢,但是資料是最安全的。 # everysec:每秒鐘呼叫一次fsync(),這是效能和安全的折中選擇。預設情況下為該模式
no-appendfsync-on-rewrite no  #當fsync方式設定為always或everysec時,如果後臺持久化程序需要執行一個很大的磁碟IO操作,那麼Redis可能會在fsync()呼叫時卡住。 目前尚未修復這個問題,這是因為即使我們在另一個新的執行緒中去執行fsync(),也會阻塞住同步寫呼叫。為了緩解這個問題,我們可以使用該配置項,這樣的話,當BGSAVE或BGWRITEAOF執行時,fsync()在主程序中的呼叫會被阻止。 這意味著當另一路程序正在對AOF檔案進行重構時,Redis的持久化功能就失效了,就好像我們設定了"appendsync no"一樣。 如果Redis有時延問題,那麼可以將該選項設定為yes。否則請保持no,因為這是保證資料完整性的最安全的選擇。

auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb  #我們允許Redis自動重寫aof。當aof增長到一定規模時,Redis會隱式呼叫BGREWRITEAOF來重寫log檔案,以縮減檔案體積。Redis是這樣工作的:Redis會記錄上次重寫時的aof大小。假如Redis自啟動至今還沒有進行過重寫,那麼啟動時aof檔案的大小會被作為基準值。 這個基準值會和當前的aof大小進行比較。如果當前aof大小超出所設定的增長比例,則會觸發重寫。另外還需要設定一個最小大小,是為了防止在aof很小時就觸發重寫。如果設定auto-aof-rewrite-percentage為0,則會關閉此重寫功能。

aof-load-truncated yes  #由於某種原因(aof檔案損壞)有可能導致利用aof檔案恢復redis資料時發生異常,該引數決定redis服務接下來的行為。如果設定為yes,則aof檔案會被載入(但資料一定不全),並且會記錄日誌說明情況。如果設定為no,則redis服務根本就啟動不起來。
aof-use-rdb-preamble yes   #為了讓使用者能夠同時擁有RDB和AOF兩種持久化的優點, 從Redis 4.0版本開始,就推出了一個能夠“魚和熊掌兼得”的持久化方案 —— RDB-AOF 混合持久化: 這種持久化能夠通過 AOF 重寫操作創建出一個同時包含RDB資料和AOF資料的AOF檔案, 其中RDB資料位於AOF檔案的開頭, 它們儲存了伺服器開始執行重寫操作時的資料庫狀態:至於那些在重寫操作執行之後執行的Redis命令,則會繼續以AOF格式追加到AOF檔案的末尾,也即是RDB資料之後。
lua-time-limit 5000 slowlog-log-slower-than 10000 #設定慢日誌記錄條件,超過10000微秒記錄 slowlog-max-len 128 #慢日誌最大長度 latency-monitor-threshold 0 notify-keyspace-events "" ############################## 虛擬記憶體 ############################## vm-enabled no #是否啟用虛擬記憶體機制,虛擬記憶體機將資料分頁存放, 把很少訪問的頁放到swap上,記憶體佔用多,最好關閉虛擬記憶體 vm-swap-file /var/lib/redis/redis.swap #虛擬記憶體檔案位置 vm-max-memory 0 #redis使用的最大記憶體上限,保護redis不會因過多使用實體記憶體影響效能 vm-page-size 32 #每個頁面的大小為32位元組 vm-pages 134217728 #設定swap檔案中頁面數量 vm-max-threads 4 #訪問swap檔案的執行緒數 ############################## 高階配置 ############################## hash-max-ziplist-entries 512 #雜湊表中元素(條目)總個數不超過設定數量時,採用線性緊湊格式儲存來節省空間 hash-max-ziplist-value 64 #雜湊表中每個value的長度不超過多少位元組時,採用線性緊湊格式儲存來節省空間 list-max-ziplist-entries 512 #list資料型別多少節點以下會採用去指標的緊湊儲存格式 list-max-ziplist-value 64 #list資料型別節點值大小小於多少位元組會採用緊湊儲存格式 list-compress-depth 0 set-max-intset-entries 512 #set資料型別內部資料如果全部是數值型,且包含多少節點以下會採用緊湊格式儲存 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes # 指定是否啟用重置雜湊,預設為開啟 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes
  • 5、PHP中使用redis

在php中使用redis,必須安裝php的redis擴充套件模組,pecl方法安裝如下:

/usr/local/php-fpm/bin/pecl install redis

vi  /usr/local/php/etc/php.ini  //增加extension = redis.so

原始碼安裝redis擴充套件如下:

wget https://github.com/phpredis/phpredis/archive/4.2.0.tar.gz
mv 4.2.0.tar.gz  php-redis.tar.gz
tar zxvf php-redis.tar.gz
cd phpredis-4.2.0/
/usr/local/php-fpm/bin/phpize
./configure --with-php-config=/usr/local/php-fpm/bin/php-config
make && make install
vi  /usr/local/php/etc/php.ini  //增加extension = redis.so

php中使用redis進行session儲存:

root@localhost ~]# vim /etc/php.ini 
[Session]    #在Session模組下增加
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

[root@localhost ~]# php-fpm -t
[16-Apr-2019 16:15:16] NOTICE: configuration file /etc/php-fpm.conf test is successful

[root@localhost ~]# systemctl reload php-fpm

建立測試檔案,進行測試session儲存:

[root@localhost ~]# wget http://study.lishiming.net/.mem_se.txt
[root@localhost ~]# mv .mem_se.txt session.php

[root@localhost ~]# php session.php 
1555402526<br><br>1555402526<br><br>n0r96n9fdkdctv2jcossvog4vq 

[root@localhost ~]# redis-cli 
127.0.0.1:6379> KEYS *
1) "PHPREDIS_SESSION:n0r96n9fdkdctv2jcossvog4vq"
2) "ke1"

127.0.0.1:6379> GET PHPREDIS_SESSION:n0r96n9fdkdctv2jcossvog4vq
"TEST|i:1555402526;TEST3|i:1555402526;"