1. 程式人生 > 實用技巧 >Redis教程——檢視閱讀

Redis教程——檢視閱讀

Redis教程——檢視閱讀

參考

Redis教程——菜鳥——藍本——3.2.100

Redis教程——w3c——3.2.100

Redis教程——w3c——Redis開發運維實踐指南

Redis教程——w3c——Redis 設計與實現(第二版)

Redis中文教程——3.2.100

Redis教程——C語言中文網——藍本2——3.2.100

Redis教程——極客——3.0

Redis教程——極客——最新版——Redis 原始碼日誌

Redis教程——Redis 原始碼日誌——面向高階教程

Redis教程——Redis 原始碼日誌——面向高階教程完整版——藍本2

Redis教程——極客——Redis Book

Redis部落格——知乎——1

Redis部落格——知乎——2

Redis之父:Salvatore Sanfilippo

  • 基於Redis3.2.100

問題

Redis 有哪些資料型別,可參考《Redis常見的5種不同的資料型別詳解》

Redis 內部結構

Redis 使用場景

Redis 持久化機制,可參考《使用快照和AOF將Redis資料持久化到硬碟中》

Redis 叢集方案與實現

Redis 為什麼是單執行緒的?

快取雪崩、快取穿透、快取預熱、快取更新、快取降級

使用快取的合理性問題

Redis常見的回收策略

略讀

菜鳥

基本上是redis的基本操作和基本資料結構知識,最後是redis的一些高階操作,總的來說都是直接面對redis伺服器的操作。

W3C

比菜鳥多擴充套件了redis面試題和分散式鎖的使用。

Redis中文教程

比菜鳥多擴充套件了redis面試題和redis與其他快取的對比,還有與ES的對比,這個有什麼好對比的呢?

C語言中文網

注重redis的應用,特別是在spring和java中結合專案的使用,提供spring專案中整合redis使用CRUD的實踐,場景等。redis的主從複雜和哨兵模式的介紹。還有個搶紅包併發示例,值得一學。

極客

講了redis的高可用和叢集

Redis 原始碼日誌

高階讀物,深入底層原始碼。

文章

Redis簡明教程

Redis是一個開源的、基於記憶體的資料結構儲存器,可以用作資料庫、快取和訊息中介軟體。

自己實現一個快取?

一般用Map實現,如果HashMap、TreeMap這些都執行緒不安全,那就用HashTable或者ConcurrentHashMap。

不管你用什麼樣的Map,它的背後都是key-value的Hash表結構,目的就是為了實現O(1)複雜度的查詢演算法,Redis也是這樣實現的,另一個常用的快取框架Memcached也是。

Hash表就是一個數組,而這個陣列的元素,是一個連結串列。

想象一下,如果連結串列越來越長,會有什麼問題?

很明顯,連結串列越長,Hash表的查詢、插入、刪除等操作的效能都會下降,極端情況下,如果全部元素都放到了一個連結串列裡頭,複雜度就會降為O(n),也就和順序查詢演算法無異了。(正因如此,Java8裡頭的HashMap在元素增長到一定程度時會從連結串列轉成一顆紅黑樹,來減緩查詢效能的下降)

怎麼解決?rehash。

Redis的Server是單執行緒伺服器,基於Event-Loop模式來處理Client的請求,這一點和NodeJS很相似。使用單執行緒的好處包括:

  • 不必考慮執行緒安全問題。很多操作都不必加鎖,既簡化了開發,又提高了效能;
  • 減少執行緒切換損耗的時間。執行緒一多,CPU線上程之間切來切去是非常耗時的,單執行緒伺服器則沒有了這個煩惱;

叢集

  • 擴大快取容量;
  • 提升吞吐量;

主從複製——Master-Slave模式

  • 資料可用性差:如果其中一臺Redis掛了,那麼上面全部的快取資料都會丟失,導致原來可以從快取中獲取的請求,都去訪問資料庫了,資料庫壓力陡增。
  • 資料查詢緩慢:監測發現,每天有一段時間,Redis 1的訪問量非常高,而且大多數請求都是去查一個相同的快取資料,導致Redis 1非常忙碌,吞吐量不足以支撐這個高的查詢負載。

Master/slave chains的架構:解決Master進行資料備份的工作量變大問題。

Redis-超詳細的教程

redis常見效能問題和解決方案:

  • (1) Master最好不要做任何持久化工作,如RDB記憶體快照和AOF日誌檔案
  • (2) 如果資料比較重要,某個Slave開啟AOF備份資料,策略設定為每秒同步一次
  • (3) 為了主從複製的速度和連線的穩定性,Master和Slave最好在同一個區域網內
  • (4) 儘量避免在壓力很大的主庫上增加從庫
  • (5) 主從複製不要用圖狀結構,用單向連結串列結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3...

這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

MySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料

相關知識:redis 記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰策略。

redis 提供 6種資料淘汰策略:

  1. voltile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰
  2. volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選將要過期的資料淘汰
  3. volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰
  4. allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰
  5. allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰
  6. no-enviction(驅逐):禁止驅逐資料

Redis 常見的效能問題都有哪些?如何解決?

  • 1).Master寫記憶體快照,save命令排程rdbSave函式,會阻塞主執行緒的工作,當快照比較大時對效能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫記憶體快照。
  • 2).Master AOF持久化,如果不重寫AOF檔案,這個持久化方式對效能的影響是最小的,但是AOF檔案會不斷增大,AOF檔案過大會影響Master重啟的恢復速度。Master最好不要做任何持久化工作,包括記憶體快照和AOF日誌檔案,特別是不要啟用記憶體快照做持久化,如果資料比較關鍵,某個Slave開啟AOF備份資料,策略為每秒同步一次。
  • 3).Master呼叫BGREWRITEAOF重寫AOF檔案,AOF在重寫的時候會佔大量的CPU和記憶體資源,導致服務load過高,出現短暫服務暫停現象。
  • 4). Redis主從複製的效能問題,為了主從複製的速度和連線的穩定性,Slave和Master最好在同一個區域網內

Redis 簡介

REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。

Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。

它通常被稱為資料結構伺服器,因為值(value)可以是 字串(String), 雜湊(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等型別。

Redis 與其他 key - value 快取產品有以下三個特點:

  • Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
  • Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等其他資料結構的儲存。
  • Redis支援資料的備份,即master-slave模式的資料備份。

Redis 優勢

  • 效能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
  • 操作原子性 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
  • 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。

Redis與其他key-value儲存有什麼不同?

  • Redis有著更為複雜的資料結構並且提供對他們的原子性操作,這是一個不同於其他資料庫的進化路徑。Redis的資料型別都是基於基本資料結構的同時對程式設計師透明,無需進行額外的抽象。
  • Redis執行在記憶體中但是可以持久化到磁碟,所以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大於硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁碟上相同的複雜的資料結構,在記憶體中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。同時,在磁碟格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。

Redis 安裝

安裝參考

windows安裝

#解壓完成後,cmd開啟命令視窗。可以把 redis 的路徑加到系統的環境變數裡,這樣就省得再輸路徑了,後面的那個 #redis.windows.conf 可以省略,如果省略,會啟用預設的。
#開啟redis伺服器
redis-server.exe redis.windows.conf

#redis客戶端連線
redis-cli.exe -h 127.0.0.1 -p 6379

Linux 下安裝

Ubuntu 下安裝

//

Redis 配置

Redis 的配置檔案位於 Redis 安裝目錄下,檔名為 redis.conf(Windows 名為 redis.windows.conf)。

你可以通過 CONFIG 命令檢視或設定配置項。命令大小寫不敏感。

127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "warning"
#使用 * 號獲取所有配置項
CONFIG GET *

Redis 配置可以通過修改 redis.conf 檔案或使用 CONFIG set 命令來修改配置。

127.0.0.1:6379> config set loglevel notice
OK
127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "notice"

redis.conf 配置項說明如下:

序號 配置項 說明
1 daemonize no Redis 預設不是以守護程序的方式執行,可以通過該配置項修改,使用 yes 啟用守護程序(Windows 不支援守護執行緒的配置為 no )
2 pidfile /var/run/redis.pid 當 Redis 以守護程序方式執行時,Redis 預設會把 pid 寫入 /var/run/redis.pid 檔案,可以通過 pidfile 指定
3 port 6379 指定 Redis 監聽埠,預設埠為 6379,作者在自己的一篇博文中解釋了為什麼選用 6379 作為預設埠,因為 6379 在手機按鍵上 MERZ 對應的號碼,而 MERZ 取自義大利歌女 Alessia Merz 的名字
4 bind 127.0.0.1 繫結的主機地址
5 timeout 300 當客戶端閒置多長秒後關閉連線,如果指定為 0 ,表示關閉該功能
6 loglevel notice 指定日誌記錄級別,Redis 總共支援四個級別:debug、verbose、notice、warning,預設為 notice
7 logfile stdout 日誌記錄方式,預設為標準輸出,如果配置 Redis 為守護程序方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會發送給 /dev/null
8 databases 16 設定資料庫的數量,預設資料庫為0,可以使用SELECT 命令在連線上指定資料庫id
9 save Redis 預設配置檔案中提供了三個條件:save 900 1save 300 10save 60 10000分別表示 900 秒(15 分鐘)內有 1 個更改,300 秒(5 分鐘)內有 10 個更改以及 60 秒內有 10000 個更改。 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合
10 rdbcompression yes 指定儲存至本地資料庫時是否壓縮資料,預設為 yes,Redis 採用 LZF 壓縮,如果為了節省 CPU 時間,可以關閉該選項,但會導致資料庫檔案變的巨大
11 dbfilename dump.rdb 指定本地資料庫檔名,預設值為 dump.rdb
12 dir ./ 指定本地資料庫存放目錄
13 slaveof 設定當本機為 slav 服務時,設定 master 服務的 IP 地址及埠,在 Redis 啟動時,它會自動從 master 進行資料同步
14 masterauth 當 master 服務設定了密碼保護時,slav 服務連線 master 的密碼
15 requirepass foobared 設定 Redis 連線密碼,如果配置了連線密碼,客戶端在連線 Redis 時需要通過 AUTH 命令提供密碼,預設關閉
16 maxclients 128 設定同一時間最大客戶端連線數,預設無限制,Redis 可以同時開啟的客戶端連線數為 Redis 程序可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis 會關閉新的連線並向客戶端返回 max number of clients reached 錯誤資訊
17 maxmemory 指定 Redis 最大記憶體限制,Redis 在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis 會先嚐試清除已到期或即將到期的 Key,當此方法處理 後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis 新的 vm 機制,會把 Key 存放記憶體,Value 會存放在 swap 區
18 appendonly no 指定是否在每次更新操作後進行日誌記錄,Redis 在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis 本身同步資料檔案是按上面 save 條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為 no
19 appendfilename appendonly.aof 指定更新日誌檔名,預設為 appendonly.aof
20 appendfsync everysec 指定更新日誌條件,共有 3 個可選值:no:表示等作業系統進行資料快取同步到磁碟(快)always:表示每次更新操作後手動呼叫 fsync() 將資料寫到磁碟(慢,安全)everysec:表示每秒同步一次(折中,預設值)
21 vm-enabled no 指定是否啟用虛擬記憶體機制,預設值為 no,簡單的介紹一下,VM 機制將資料分頁存放,由 Redis 將訪問量較少的頁即冷資料 swap 到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中(在後面的文章我會仔細分析 Redis 的 VM 機制)
22 vm-swap-file /tmp/redis.swap 虛擬記憶體檔案路徑,預設值為 /tmp/redis.swap,不可多個 Redis 例項共享
23 vm-max-memory 0 將所有大於 vm-max-memory 的資料存入虛擬記憶體,無論 vm-max-memory 設定多小,所有索引資料都是記憶體儲存的(Redis 的索引資料 就是 keys),也就是說,當 vm-max-memory 設定為 0 的時候,其實是所有 value 都存在於磁碟。預設值為 0
24 vm-page-size 32 Redis swap 檔案分成了很多的 page,一個物件可以儲存在多個 page 上面,但一個 page 上不能被多個物件共享,vm-page-size 是要根據儲存的 資料大小來設定的,作者建議如果儲存很多小物件,page 大小最好設定為 32 或者 64bytes;如果儲存很大大物件,則可以使用更大的 page,如果不確定,就使用預設值
25 vm-pages 134217728 設定 swap 檔案中的 page 數量,由於頁表(一種表示頁面空閒或使用的 bitmap)是在放在記憶體中的,,在磁碟上每 8 個 pages 將消耗 1byte 的記憶體。
26 vm-max-threads 4 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4
27 glueoutputbuf yes 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟
28 hash-max-zipmap-entries 64 hash-max-zipmap-value 512 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演算法
29 activerehashing yes 指定是否啟用重置雜湊,預設為開啟(後面在介紹 Redis 的雜湊演算法時具體介紹)
30 include /path/to/local.conf 指定包含其它的配置檔案,可以在同一主機上多個Redis例項之間使用同一份配置檔案,而同時各個例項又擁有自己的特定配置檔案

Redis 資料型別

Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。

String(字串)

string 是 redis 最基本的型別,你可以理解成與 Memcached 一模一樣的型別,一個 key 對應一個 value。

string 型別是二進位制安全的。意思是 redis 的 string 可以包含任何資料。比如jpg圖片或者序列化的物件。

string 型別是 Redis 最基本的資料型別,string 型別的值最大能儲存 512MB。

Hash(雜湊)

Redis hash 是一個鍵值(key=>value)對集合。

Redis hash 是一個 string 型別的 field 和 value 的對映表,hash 特別適合用於儲存物件。

使用了 Redis HMSET, HGET 命令,HMSET 設定了兩個 field=>value 對, HGET 獲取對應 field 對應的 value。

每個 hash 可以儲存 2^32-1 鍵值對(40多億)。

List(列表)

Redis 列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)。

每個列表最多可儲存 2^32 - 1 元素 。

Set(集合)

Redis 的 Set 是 string 型別的無序集合。相當於HashSet。

集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。

Set集合內元素具有唯一性,第二次插入的元素將被忽略 。

每個集合中最大的成員數為 2^32 - 1 .

zset(sorted set:有序集合)

Redis zset 和 set 一樣也是string型別元素的集合,且不允許重複的成員。

不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。

zset的成員是唯一的,但分數(score)卻可以重複。

擴充套件:

各個資料型別應用場景:

型別 簡介 特性 場景
String(字串) 二進位制安全 可以包含任何資料,比如jpg圖片或者序列化的物件,一個鍵最大能儲存512M ---
Hash(字典) 鍵值對集合,即程式語言中的Map型別 適合儲存物件,並且可以像資料庫中update一個屬性一樣只修改某一項屬性值(Memcached中需要取出整個字串反序列化成物件修改完再序列化存回去) 儲存、讀取、修改使用者屬性
List(列表) 連結串列(雙向連結串列) 增刪快,提供了操作某一段元素的API 1,最新訊息排行等功能(比如朋友圈的時間線) 2,訊息佇列
Set(集合) 雜湊表實現,元素不重複 1、新增、刪除,查詢的複雜度都是O(1) 2、為集合提供了求交集、並集、差集等操作 1、共同好友 2、利用唯一性,統計訪問網站的所有獨立ip 3、好友推薦時,根據tag求交集,大於某個閾值就可以推薦
Sorted Set(有序集合) 將Set中的元素增加一個權重引數score,元素按score有序排列 資料插入集合時,已經進行天然排序 1、排行榜 2、帶權重的訊息佇列

注意:Redis支援多個數據庫,並且每個資料庫的資料是隔離的不能共享,並且基於單機才有,如果是叢集就沒有資料庫的概念。

Redis是一個字典結構的儲存伺服器,而實際上一個Redis例項提供了多個用來儲存資料的字典,客戶端可以指定將資料儲存在哪個字典中。這與我們熟知的在一個關係資料庫例項中可以建立多個數據庫類似,所以可以將其中的每個字典都理解成一個獨立的資料庫。

每個資料庫對外都是一個從0開始的遞增數字命名,Redis預設支援16個數據庫(可以通過配置檔案支援更多,無上限),可以通過配置databases來修改這一數字。客戶端與Redis建立連線後會自動選擇0號資料庫,不過可以隨時使用SELECT命令更換資料庫,如要選擇1號資料庫:

redis> SELECT 1
OK
redis [1] > GET foo
(nil)

然而這些以數字命名的資料庫又與我們理解的資料庫有所區別。首先Redis不支援自定義資料庫的名字,每個資料庫都以編號命名,開發者必須自己記錄哪些資料庫儲存了哪些資料。另外Redis也不支援為每個資料庫設定不同的訪問密碼,所以一個客戶端要麼可以訪問全部資料庫,要麼連一個數據庫也沒有許可權訪問。最重要的一點是多個數據庫之間並不是完全隔離的,比如FLUSHALL命令可以清空一個Redis例項中所有資料庫中的資料。綜上所述,這些資料庫更像是一種名稱空間,而不適宜儲存不同應用程式的資料。比如可以使用0號資料庫儲存某個應用生產環境中的資料,使用1號資料庫儲存測試環境中的資料,但不適宜使用0號資料庫儲存A應用的資料而使用1號資料庫B應用的資料,不同的應用應該使用不同的Redis例項儲存資料。由於Redis非常輕量級,一個空Redis例項佔用的內在只有1M左右,所以不用擔心多個Redis例項會額外佔用很多記憶體。

示例:

#開啟客戶端連線
F:\redis>redis-cli.exe -h 127.0.0.1 -p 6379
#開啟預設連線本地的客戶端
redis-cli.exe
#字串操作
127.0.0.1:6379> set hero "batman dark knight"
OK
127.0.0.1:6379> get hero
"batman dark knight"
#Hash(雜湊)操作 可以用hmset/hmget, 或者hset/hget
127.0.0.1:6379> hmset car tire "good year"
OK
127.0.0.1:6379> hmset car corlor "black"
OK
127.0.0.1:6379> hmget car corlor
1) "black"
127.0.0.1:6379> hget car tire
"good year"
#List(列表)lpush 在左邊插入 ,rpush 在最右邊插入,lrange 遍歷List
127.0.0.1:6379> lpush fruit apple
(integer) 1
127.0.0.1:6379> lpush fruit orange banana
(integer) 3
127.0.0.1:6379> lpush fruit watermelon berry
(integer) 5
127.0.0.1:6379> lrange fruit 0 10
1) "berry"
2) "watermelon"
3) "banana"
4) "orange"
5) "apple"
#Set(集合)操作,sadd 新增 smembers 遍歷set
127.0.0.1:6379> sadd animal tiger rabbit cow monkey
(integer) 4
127.0.0.1:6379> sadd animal cat dog
(integer) 2
127.0.0.1:6379> sadd animal sheep
(integer) 1
127.0.0.1:6379> smembers animal
1) "tiger"
2) "monkey"
3) "rabbit"
4) "cow"
5) "dog"
6) "cat"
7) "sheep"
#zset(sorted set:有序集合)操作,zadd 新增 zrangebyscore 或zrange 遍歷zset
#zadd hourse 0 wall 在使用zadd 新增元素時會給一個分值,作為排序大小,當zrange時會從小到大排列遍歷,當
#分數值相同時從值的首字母按a-z排序
127.0.0.1:6379> zadd body 0 nose
(integer) 1
127.0.0.1:6379> zadd body 0 head
(integer) 1
127.0.0.1:6379> zadd body 0 face
(integer) 1
127.0.0.1:6379> zrangebyscore body 0 10
1) "face"
2) "head"
3) "nose"
127.0.0.1:6379> zadd hourse 0 wall
(integer) 1
127.0.0.1:6379> zadd hourse 10 windows
(integer) 1
127.0.0.1:6379> zadd hourse 11 table
(integer) 1
127.0.0.1:6379> zadd hourse 12 frudge
(integer) 1
127.0.0.1:6379> zadd hourse 13 box
(integer) 1
127.0.0.1:6379> zrangebyscore hourse 0 100
1) "wall"
2) "windows"
3) "table"
4) "frudge"
5) "box"
127.0.0.1:6379> zrange hourse 0 100
1) "wall"
2) "windows"
3) "table"
4) "frudge"
5) "box"
127.0.0.1:6379> zrange body 0 100
1) "face"
2) "head"
3) "nose"
127.0.0.1:6379>
#刪除
del key

Redis 命令

#連線到主機為 127.0.0.1,埠為 6379 ,密碼為 mypass 的 redis 服務上。
redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
#有時候會有中文亂碼。
#要在 redis-cli 後面加上 --raw
redis-cli --raw

Redis 鍵(key)

Redis 鍵相關的基本命令:

序號 命令及描述
1 DEL key 該命令用於在 key 存在時刪除 key。
2 DUMP key 序列化給定 key ,並返回被序列化的值。
3 EXISTS key 檢查給定 key 是否存在。
4 EXPIRE key seconds 為給定 key 設定過期時間,以秒計。
5 EXPIREAT key timestamp EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設定過期時間。 不同在於 EXPIREAT 命令接受的時間引數是 UNIX 時間戳(unix timestamp)。
6 PEXPIRE key milliseconds 設定 key 的過期時間以毫秒計。
7 PEXPIREAT key milliseconds-timestamp 設定 key 過期時間的時間戳(unix timestamp) 以毫秒計
8 KEYS pattern 查詢所有符合給定模式( pattern)的 key 。
9 MOVE key db 將當前資料庫的 key 移動到給定的資料庫 db 當中。
10 PERSIST key 移除 key 的過期時間,key 將持久保持。
11 PTTL key 以毫秒為單位返回 key 的剩餘的過期時間。
12 TTL key 以秒為單位,返回給定 key 的剩餘生存時間(TTL, time to live)。
13 RANDOMKEY 從當前資料庫中隨機返回一個 key 。
14 RENAME key newkey 修改 key 的名稱
15 RENAMENX key newkey 僅當 newkey 不存在時,將 key 改名為 newkey 。
16 SCAN cursor [MATCH pattern] [COUNT count] 迭代資料庫中的資料庫鍵。
17 TYPE key 返回 key 所儲存的值的型別。

Redis 字串(String)

常用的 redis 字串命令:

序號 命令及描述
1 SET key value 設定指定 key 的值
2 GET key 獲取指定 key 的值。
3 GETRANGE key start end 返回 key 中字串值的子字元
4 GETSET key value 將給定 key 的值設為 value ,並返回 key 的舊值(old value)。
5 GETBIT key offset 對 key 所儲存的字串值,獲取指定偏移量上的位(bit)。
6 [MGET key1 key2..] 獲取所有(一個或多個)給定 key 的值。
7 SETBIT key offset value 對 key 所儲存的字串值,設定或清除指定偏移量上的位(bit)。
8 SETEX key seconds value 將值 value 關聯到 key ,並將 key 的過期時間設為 seconds (以秒為單位)。
9 SETNX key value 只有在 key 不存在時設定 key 的值。
10 SETRANGE key offset value 用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 offset 開始。
11 STRLEN key 返回 key 所儲存的字串值的長度。
12 [MSET key value key value ...] 同時設定一個或多個 key-value 對。
13 [MSETNX key value key value ...] 同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在。
14 PSETEX key milliseconds value 這個命令和 SETEX 命令相似,但它以毫秒為單位設定 key 的生存時間,而不是像 SETEX 命令那樣,以秒為單位。
15 INCR key 將 key 中儲存的數字值增一。
16 INCRBY key increment 將 key 所儲存的值加上給定的增量值(increment) 。
17 INCRBYFLOAT key increment 將 key 所儲存的值加上給定的浮點增量值(increment) 。
18 DECR key 將 key 中儲存的數字值減一。
19 DECRBY key decrement key 所儲存的值減去給定的減量值(decrement) 。
20 APPEND key value 如果 key 已經存在並且是一個字串, APPEND 命令將指定的 value 追加到該 key 原來值(value)的末尾。

Redis 雜湊(Hash)

Redis hash 是一個 string 型別的 field 和 value 的對映表,hash 特別適合用於儲存物件。

注意:雜湊表的field 和 value都是String型別的,當我們要往裡塞其他雜湊表或者List集合等時,必須用FastJson等工具轉化為字串型別。

redis hash 基本的相關命令:

序號 命令及描述
1 [HDEL key field1 field2] 刪除一個或多個雜湊表字段
2 HEXISTS key field 檢視雜湊表 key 中,指定的欄位是否存在。
3 HGET key field 獲取儲存在雜湊表中指定欄位的值。
4 HGETALL key 獲取在雜湊表中指定 key 的所有欄位和值
5 HINCRBY key field increment 為雜湊表 key 中的指定欄位的整數值加上增量 increment,increment可以是正負數 。
6 HINCRBYFLOAT key field increment 為雜湊表 key 中的指定欄位的浮點數值加上增量 increment,increment可以是正負數。
7 HKEYS key 獲取所有雜湊表中的欄位
8 HLEN key 獲取雜湊表中欄位的數量
9 [HMGET key field1 field2] 獲取所有給定欄位的值
10 [HMSET key field1 value1 field2 value2 ] 同時將多個 field-value (域-值)對設定到雜湊表 key 中。
11 HSET key field value 將雜湊表 key 中的欄位 field 的值設為 value 。
12 HSETNX key field value 只有在欄位 field 不存在時,設定雜湊表字段的值。
13 HVALS key 獲取雜湊表中所有值。
14 HSCAN key cursor [MATCH pattern] [COUNT count] 迭代雜湊表中的鍵值對。

Redis 列表(List)

Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊) 。

列表相關的基本命令:

序號 命令及描述
1 [BLPOP key1 key2 ] timeout 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
2 [BRPOP key1 key2 ] timeout 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
3 BRPOPLPUSH source destination timeout 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
4 LINDEX key index 通過索引獲取列表中的元素
5 LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者後插入元素
6 LLEN key 獲取列表長度
7 LPOP key 移出並獲取列表的第一個元素
8 [LPUSH key value1 value2] 將一個或多個值插入到列表頭部
9 LPUSHX key value 將一個值插入到已存在的列表頭部
10 LRANGE key start stop 獲取列表指定範圍內的元素
11 LREM key count value 移除列表元素
12 LSET key index value 通過索引設定列表元素的值
13 LTRIM key start stop 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。
14 RPOP key 移除列表的最後一個元素,返回值為移除的元素。
15 RPOPLPUSH source destination 移除列表的最後一個元素,並將該元素新增到另一個列表並返回
16 [RPUSH key value1 value2] 在列表中新增一個或多個值
17 RPUSHX key value 為已存在的列表新增值

Redis 集合(Set)

Redis 的 Set 是 String 型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。

Redis 中集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。

Redis 集合基本命令:

序號 命令及描述
1 [SADD key member1 member2] 向集合新增一個或多個成員
2 SCARD key 獲取集合的成員數
3 [SDIFF key1 key2] 返回給定集合key1與其他集合的差集
4 [SDIFFSTORE destination key1 key2] 返回給定集合key1與其他集合的差集並存儲在 destination 中
5 [SINTER key1 key2] 返回給定所有集合的交集
6 [SINTERSTORE destination key1 key2] 返回給定所有集合的交集並存儲在 destination 中
7 SISMEMBER key member 判斷 member 元素是否是集合 key 的成員
8 SMEMBERS key 返回集合中的所有成員
9 SMOVE source destination member 將 member 元素從 source 集合移動到 destination 集合,如果destination 集合已經包含了這個元素,也會從source 集合移出,只是destination 集合已經有值了所以沒變。
10 SPOP key 移除並返回集合中的一個隨機元素
11 [SRANDMEMBER key count] 返回集合中一個或多個隨機元素
12 [SREM key member1 member2] 移除集合中一個或多個成員
13 [SUNION key1 key2] 返回所有給定集合的並集
14 [SUNIONSTORE destination key1 key2] 所有給定集合的並集儲存在 destination 集合中
15 SSCAN key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素

Redis 有序集合(sorted set)

Redis 有序集合和集合一樣也是string型別元素的集合,且不允許重複的成員。

不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。

有序集合的成員是唯一的,但分數(score)卻可以重複。

集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。

原文中說,集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)其實不太準確。

其實在redis sorted sets裡面當items內容大於64的時候同時使用了hash和skiplist兩種設計實現。這也會為了排序和查詢效能做的優化。所以如上可知:

新增和刪除都需要修改skiplist,所以複雜度為O(log(n))。

但是如果僅僅是查詢元素的話可以直接使用hash,其複雜度為O(1)

其他的range操作複雜度一般為O(log(n))

當然如果是小於64的時候,因為是採用了ziplist的設計,其時間複雜度為O(n)

redis 有序集合的基本命令:

序號 命令及描述
1 [ZADD key score1 member1 score2 member2] 向有序集合新增一個或多個成員,或者更新已存在成員的分數
2 ZCARD key 獲取有序集合的成員數
3 ZCOUNT key min max 計算在有序集合中指定區間分數的成員數
4 ZINCRBY key increment member 有序集合中對指定成員的分數加上增量 increment
5 [ZINTERSTORE destination numkeys key key ...] 計算給定的一個或多個有序集的交集並將結果集儲存在新的有序集合 key 中,numkeys表示有幾個集合取交集
6 ZLEXCOUNT key min max 在有序集合中計算指定字典區間內成員數量
7 [ZRANGE key start stop WITHSCORES] 通過索引區間返回有序集合指定區間內的成員
8 [ZRANGEBYLEX key min max LIMIT offset count] 通過字典區間返回有序集合的成員
9 ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通過分數返回有序集合指定區間內的成員
10 ZRANK key member 返回有序集合中指定成員的索引
11 [ZREM key member member ...] 移除有序集合中的一個或多個成員
12 ZREMRANGEBYLEX key min max 移除有序集合中給定的字典區間的所有成員
13 ZREMRANGEBYRANK key start stop 移除有序集合中給定的排名區間的所有成員
14 ZREMRANGEBYSCORE key min max 移除有序集合中給定的分數區間的所有成員
15 [ZREVRANGE key start stop WITHSCORES] 返回有序集中指定區間內的成員,通過索引,分數從高到低
16 [ZREVRANGEBYSCORE key max min WITHSCORES] 返回有序集中指定分數區間內的成員,分數從高到低排序
17 ZREVRANK key member 返回有序集合中指定成員的排名,有序整合員按分數值遞減(從大到小)排序
18 ZSCORE key member 返回有序集中,成員的分數值
19 [ZUNIONSTORE destination numkeys key key ...] 計算給定的一個或多個有序集的並集,並存儲在新的 key 中
20 ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成員和元素分值)

Redis HyperLogLog

什麼是基數?

比如資料集 {1, 3, 5, 7, 5, 7, 8}, 那麼這個資料集的基數集為 {1, 3, 5 ,7, 8}, 基數(不重複元素)為5。 基數估計就是在誤差可接受的範圍內,快速計算基數。

Redis 在 2.8.9 版本添加了 HyperLogLog 結構。

Redis HyperLogLog 是用來做基數統計的演算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。

在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。

但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。

redis HyperLogLog 的基本命令:

序號 命令及描述
1 [PFADD key element element ...] 新增指定元素到 HyperLogLog 中。
2 [PFCOUNT key key ...] 返回給定 HyperLogLog 的基數估算值。
3 [PFMERGE destkey sourcekey sourcekey ...] 將多個 HyperLogLog 合併為一個 HyperLogLog

Redis 釋出訂閱

Redis 釋出訂閱(pub/sub)是一種訊息通訊模式:傳送者(pub)傳送訊息,訂閱者(sub)接收訊息。

Redis 客戶端可以訂閱任意數量的頻道。

redis 釋出訂閱常用命令:

序號 命令及描述
1 [PSUBSCRIBE pattern pattern ...] 訂閱一個或多個符合給定模式的頻道。
2 PUBSUB subcommand [argument [argument ...]] 檢視訂閱與釋出系統狀態。
3 PUBLISH channel message 將資訊傳送到指定的頻道。
4 PUNSUBSCRIBE [pattern [pattern ...]] 退訂所有給定模式的頻道。
5 [SUBSCRIBE channel channel ...] 訂閱給定的一個或多個頻道的資訊。
6 UNSUBSCRIBE [channel [channel ...]] 指退訂給定的頻道。

例項:

Redis 事務

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

  • 批量操作在傳送 EXEC 命令前被放入佇列快取。
  • 收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其餘的命令依然被執行。
  • 在事務執行過程,其他客戶端提交的命令請求不會插入到事務執行命令序列中。

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

  • 開始事務。
  • 命令入隊。
  • 執行事務。

注意:單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執行並不是原子性的。

事務可以理解為一個打包的批量執行指令碼,但批量指令並非原子化的操作,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

redis 事務的相關命令:

序號 命令及描述
1 DISCARD 取消事務,放棄執行事務塊內的所有命令。
2 EXEC 執行所有事務塊內的命令。
3 MULTI 標記一個事務塊的開始。
4 UNWATCH 取消 WATCH 命令對所有 key 的監視。
5 [WATCH key key ...] 監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

示例:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set godfather mike
QUEUED
127.0.0.1:6379> set blacked xuwenbiao
QUEUED
127.0.0.1:6379> sadd family me father mother sister wife "bro in law"
QUEUED
127.0.0.1:6379> get godfather
QUEUED
127.0.0.1:6379> get blacked
QUEUED
127.0.0.1:6379> smembers family
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (integer) 6
4) "mike"
5) "xuwenbiao"
6) 1) "me"
   2) "mother"
   3) "bro in law"
   4) "wife"
   5) "father"
   6) "sister"

Redis 指令碼

Redis 指令碼使用 Lua 直譯器來執行指令碼。 Redis 2.6 版本通過內嵌支援 Lua 環境。執行指令碼的常用命令為 EVAL。

Q:Redis 指令碼的作用,使用場景是什麼?

Redis 連線

Redis 連線命令主要是用於連線 redis 服務。

Redis 連線命令

redis 連線的基本命令:

序號 命令及描述
1 AUTH password 驗證密碼是否正確
2 ECHO message 列印字串
3 PING 檢視服務是否執行
4 QUIT 關閉當前連線
5 SELECT index 切換到指定的資料庫

疑問:

Q:SELECT index 切換到指定的資料庫有什麼用,redis的資料庫是幹嘛用的?是持久化後的資料儲存的地方麼?指定不同的資料庫是為了什麼?什麼場景下這樣做?

Q:執行 AUTH "password" 報錯,報錯資訊:ERR Client sent AUTH, but no password is set。

A:這是由於redis沒有設定密碼,可以選擇設定密碼,執行該命令便不會有這個報錯。

參考

解決方案一:
  在redis配置檔案中redis.conf加入:

requirePass: 你的密碼

解決方案二:
  把上面的配置中password一行去掉,既然沒密碼,就不要寫。

spring:
	redis:
	    database: 0
	    host: 127.0.0.1
	    port: 6379
	    timeout: 10000

Redis 伺服器

Redis 伺服器命令主要是用於管理 redis 服務。

redis 伺服器的相關命令:

序號 命令及描述
1 BGREWRITEAOF 非同步執行一個 AOF(AppendOnly File) 檔案重寫操作
2 BGSAVE 在後臺非同步儲存當前資料庫的資料到磁碟
3 CLIENT KILL [ip:port] [ID client-id] 關閉客戶端連線
4 CLIENT LIST 獲取連線到伺服器的客戶端連線列表
5 CLIENT GETNAME 獲取連線的名稱
6 CLIENT PAUSE timeout 在指定時間內終止執行來自客戶端的命令
7 CLIENT SETNAME connection-name 設定當前連線的名稱
8 CLUSTER SLOTS 獲取叢集節點的對映陣列
9 COMMAND 獲取 Redis 命令詳情陣列
10 COMMAND COUNT 獲取 Redis 命令總數
11 COMMAND GETKEYS 獲取給定命令的所有鍵
12 TIME 返回當前伺服器時間
13 [COMMAND INFO command-name command-name ...] 獲取指定 Redis 命令描述的陣列
14 CONFIG GET parameter 獲取指定配置引數的值
15 CONFIG REWRITE 對啟動 Redis 伺服器時所指定的 redis.conf 配置檔案進行改寫
16 CONFIG SET parameter value 修改 redis 配置引數,無需重啟
17 CONFIG RESETSTAT 重置 INFO 命令中的某些統計資料
18 DBSIZE 返回當前資料庫的 key 的數量
19 DEBUG OBJECT key 獲取 key 的除錯資訊
20 DEBUG SEGFAULT 讓 Redis 服務崩潰
21 FLUSHALL 刪除所有資料庫的所有key
22 FLUSHDB 刪除當前資料庫的所有key
23 [INFO section] 獲取 Redis 伺服器的各種資訊和統計數值
24 LASTSAVE 返回最近一次 Redis 成功將資料儲存到磁碟上的時間,以 UNIX 時間戳格式表示
25 MONITOR 實時打印出 Redis 伺服器接收到的命令,除錯用
26 ROLE 返回主從例項所屬的角色
27 SAVE 同步儲存資料到硬碟
28 SHUTDOWN [NOSAVE] [SAVE] 非同步儲存資料到硬碟,並關閉伺服器
29 SLAVEOF host port 將當前伺服器轉變為指定伺服器的從屬伺服器(slave server)
30 [SLOWLOG subcommand argument] 管理 redis 的慢日誌
31 SYNC 用於複製功能(replication)的內部命令

Redis GEO

Redis GEO 主要用於儲存地理位置資訊,並對儲存的資訊進行操作,該功能在 Redis 3.2 版本新增。

Redis GEO 操作方法有:

  • geoadd:新增地理位置的座標。
  • geopos:獲取地理位置的座標。
  • geodist:計算兩個位置之間的距離。
  • georadius:根據使用者給定的經緯度座標來獲取指定範圍內的地理位置集合。
  • georadiusbymember:根據儲存在位置集合裡面的某個地點獲取指定範圍內的地理位置集合。
  • geohash:返回一個或多個位置物件的 geohash 值。

Q:Redis GEO 主要用於儲存地理位置資訊,並對儲存的資訊進行操作.是專門用於地理位置的命令,滴滴,谷歌地圖等用的?

Redis 高階教程

Redis 資料備份與恢復

備份

Redis SAVE 命令用於建立當前資料庫的備份。

該命令將在 redis 安裝目錄中建立dump.rdb檔案。

Bgsave

建立 redis 備份檔案也可以使用命令 BGSAVE,該命令在後臺執行。

恢復資料

如果需要恢復資料,只需將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可。獲取 redis 目錄可以使用 CONFIG 命令。

CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"

以上命令 CONFIG GET dir 輸出的 redis 安裝目錄為 /usr/local/redis/bin 。

Redis 安全

我們可以通過 redis 的配置檔案設定密碼引數,這樣客戶端連線到 redis 服務就需要密碼驗證,這樣可以讓你的 redis 服務更安全。

//檢視是否設定了密碼驗證
CONFIG get requirepass

//如果需要密碼則登入後要進行密碼授權,才能進行redis操作,如get/set等
auth "密碼"

//預設情況下 requirepass 引數是空的,這就意味著你無需通過密碼驗證就可以連線到 redis 服務。
//修改密碼命令
CONFIG set requirepass "密碼"

//如果不想要設定密碼了,可以執行命令
CONFIG set requirepass ""

Redis 效能測試

Redis 效能測試是通過同時執行多個命令實現的。

redis 效能測試的基本命令如下:

redis-benchmark [option] [option value]

注意:該命令是在 redis 的目錄下執行的,而不是 redis 客戶端的內部指令。

redis 效能測試工具可選引數如下所示:

序號 選項 描述 預設值
1 -h 指定伺服器主機名 127.0.0.1
2 -p 指定伺服器埠 6379
3 -s 指定伺服器 socket
4 -c 指定併發連線數 50
5 -n 指定請求數 10000
6 -d 以位元組的形式指定 SET/GET 值的資料大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用隨機 key, SADD 使用隨機值
9 -P 通過管道傳輸 請求 1
10 -q 強制退出 redis。僅顯示 query/sec 值
11 --csv 以 CSV 格式輸出
12 -l 生成迴圈,永久執行測試
13 -t 僅執行以逗號分隔的測試命令列表。
14 -I Idle 模式。僅開啟 N 個 idle 連線並等待。

//測試主機為 127.0.0.1,埠號為 6379,執行的命令為 set,lpush,請求數為 10000,通過 -q 引數讓結果只顯示每秒執行的請求數。
redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q

//測試本地主機
redis-benchmark.exe -n 10000 -q

//測試主機為 127.0.0.1,埠號為 6379,執行所有命令,請求數為 10000,併發數 100,通過 -q 引數讓結果只顯示每秒執行的請求數。
E:\redis>redis-benchmark.exe -h 127.0.0.1 -p 6379 -c 100 -n 10000 -q
PING_INLINE: 12300.12 requests per second
PING_BULK: 11918.95 requests per second
SET: 12239.90 requests per second
GET: 12722.65 requests per second
INCR: 12165.45 requests per second
LPUSH: 12515.64 requests per second
RPUSH: 12285.01 requests per second
LPOP: 12150.67 requests per second
RPOP: 12484.39 requests per second
SADD: 12422.36 requests per second
SPOP: 12254.90 requests per second
LPUSH (needed to benchmark LRANGE): 12330.46 requests per second
LRANGE_100 (first 100 elements): 11848.34 requests per second
LRANGE_300 (first 300 elements): 7961.78 requests per second
LRANGE_500 (first 450 elements): 6648.94 requests per second
LRANGE_600 (first 600 elements): 5646.53 requests per second
MSET (10 keys): 12722.65 requests per second

//測試主機為 127.0.0.1,埠號為 6379,執行的命令為 set,get,lpush,請求數為 10000,通過 -q 引數讓結果只顯示每秒執行的請求數。
E:\redis>redis-benchmark.exe -h 127.0.0.1 -p 6379 -t set,get,lpush -n 10000 -q
SET: 12919.90 requests per second
GET: 12804.10 requests per second
LPUSH: 12787.72 requests per second

Redis 客戶端連線

Redis 通過監聽一個 TCP 埠或者 Unix socket 的方式來接收來自客戶端的連線,當一個連線建立後,Redis 內部會進行以下一些操作:

  • 首先,客戶端 socket 會被設定為非阻塞模式,因為 Redis 在網路事件處理上採用的是非阻塞多路複用模型。
  • 然後為這個 socket 設定 TCP_NODELAY 屬性,禁用 Nagle 演算法
  • 然後建立一個可讀的檔案事件用於監聽這個客戶端 socket 的資料傳送

最大連線數

在 Redis2.4 中,最大連線數是被直接硬編碼在程式碼裡面的,而在2.6版本中這個值變成可配置的。

maxclients 的預設值是 10000,你也可以在 redis.conf 中對這個值進行修改。

//最大連線數
config get maxclients

//設定最大連線數為1000
config set maxclients 1000

//以下例項我們在服務啟動時設定最大連線數為 1000:
redis-server --maxclients 1000
//windows下
E:\redis>redis-server.exe redis.windows.conf --maxclients 1000

客戶端命令

S.N. 命令 描述
1 CLIENT LIST 返回連線到 redis 服務的客戶端列表
2 CLIENT SETNAME 設定當前連線的名稱
3 CLIENT GETNAME 獲取通過 CLIENT SETNAME 命令設定的服務名稱
4 CLIENT PAUSE 掛起客戶端連線,指定掛起的時間以毫秒計
5 CLIENT KILL 關閉客戶端連線

//掛起客戶端連線50000毫秒,這時候客戶端不能接受任何指令了,而且關閉不了,重新進入也不行,只能等待客戶端掛起時間達到後,或者關閉服務端redis伺服器,才行
client pause 50000

Redis 管道技術

Redis是一種基於客戶端-服務端模型以及請求/響應協議的TCP服務。這意味著通常情況下一個請求會遵循以下步驟:

  • 客戶端向服務端傳送一個查詢請求,並監聽Socket返回,通常是以阻塞模式,等待服務端響應。
  • 服務端處理命令,並將結果返回給客戶端。

Redis 管道技術可以在服務端未響應時,客戶端可以繼續向服務端傳送請求,並最終一次性讀取所有服務端的響應。

Q:Redis 管道技術是基於NIO麼?

Redis 分割槽

分割槽是分割資料到多個Redis例項的處理過程,因此每個例項只儲存所有key的一個子集。

分割槽的優勢

  • 通過利用多臺計算機記憶體的和值,允許我們構造更大的資料庫。
  • 通過多核和多臺計算機,允許我們擴充套件計算能力;通過多臺計算機和網路介面卡,允許我們擴充套件網路頻寬。

分割槽的不足

redis的一些特性在分割槽方面表現的不是很好:

  • 涉及多個key的操作通常是不被支援的。舉例來說,當兩個set對映到不同的redis例項上時,你就不能對這兩個set執行交集操作。
  • 涉及多個key的redis事務不能使用。
  • 當使用分割槽時,資料處理較為複雜,比如你需要處理多個rdb/aof檔案,並且從多個例項和主機備份持久化檔案。
  • 增加或刪除容量也比較複雜。redis叢集大多數支援在執行時增加、刪除節點的透明資料平衡的能力,但是類似於客戶端分割槽、代理等其他系統則不支援這項特性。然而,一種叫做presharding的技術對此是有幫助的。

分割槽型別

範圍分割槽

最簡單的分割槽方式是按範圍分割槽,就是對映一定範圍的物件到特定的Redis例項。

比如,ID從0到10000的使用者會儲存到例項R0,ID從10001到 20000的使用者會儲存到R1,以此類推。

這種方式是可行的,並且在實際中使用,不足就是要有一個區間範圍到例項的對映表。這個表要被管理,同時還需要各 種物件的對映表,通常對Redis來說並非是好的方法。

雜湊分割槽

另外一種分割槽方法是hash分割槽。這對任何key都適用,也無需是object_name:這種形式,像下面描述的一樣簡單:

  • 用一個hash函式將key轉換為一個數字,比如使用crc32 hash函式。對key foobar執行crc32(foobar)會輸出類似93024922的整數。
  • 對這個整數取模,將其轉化為0-3之間的數字,就可以將這個整數對映到4個Redis例項中的一個了。93024922 % 4 = 2,就是說key foobar應該被存到R2例項中。注意:取模操作是取除的餘數,通常在多種程式語言中用%操作符實現。

疑問:

1、Q:redis HSCAN 命令的使用場景?如何使用?

Java 使用 Redis

需要依賴Java redis 驅動 :jedis

Redis與SpringBoot整合有兩種方式,第一種是使用Jedis,它是Redis官方推薦的面向Java的操作Redis的客戶端,第二種是使用RedisTemplate,它是SpringDataRedis中對JedisApi的高度封裝。我此次使用的是RedisTemplate,並整理了redis工具類方便大家使用

示例:

spring整合jedis

jedis依賴:

    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
      <optional>true</optional>
    </dependency>

public class RedisTest {

    public static void main(String[] args) {
        //不傳引數預設是localhost
        //Jedis jedis = new Jedis();

        //本地localhost兩種傳值方式
        //Jedis jedis = new Jedis("localhost");
        Jedis jedis = new Jedis("127.0.0.1");
        System.out.println("連線成功");
        System.out.println(jedis.ping());
        jedis.set("hero", "I AM BATMAN");
        String hero = jedis.get("hero");
        System.out.println("hero 返回" + hero);

        jedis.lpush("Europe", "German");
        jedis.lpush("Europe", "France");
        jedis.lpush("Europe", "Duke");
        List<String> europe = jedis.lrange("Europe", 0, 2);
        for (String s : europe) {
            System.out.println("Europe list:" + s);
        }

        Set<String> keys = jedis.keys("*");
        for (String key : keys) {
            System.out.println("redis key:"+key);
            //不同型別的資料型別要用不同的獲取方式,否則報錯Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException:
            // WRONGTYPE Operation against a key holding the wrong kind of value
            //System.out.println("redis data :"+jedis.get(key));
        }
    }
}

輸出:

連線成功
PONG
hero 返回I AM BATMAN
Europe list:Duke
Europe list:France
Europe list:German
redis key:music
redis key:phone
redis key:hero
redis key:Europe
redis key:mylist

springboot整合redis(SpringDataRedis)

依賴:

     <!-- 配置使用 redis 啟動器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

application.yml配置

  redis:
    host: localhost # 預設localhost,需要遠端伺服器需要修改
    port: 6379  # 預設6379,如果不一致需要修改
    database: 0 # 代表連線的資料庫索引,預設為0,

單元測試:

@RunWith(SpringJUnit4ClassRunner.class)
//重點是加入@SpringBootTest註解,屬性classes用於載入引導類
@SpringBootTest(classes = MyBootApplication.class)
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void redisTest() {
        System.out.println("=================================================");
        redisTemplate.opsForValue().set("superMan", "IronMan");
        System.out.println(redisTemplate.opsForValue().get("superMan"));
        redisTemplate.opsForList().leftPushAll("Color", "紅", "橙", "黃");
        List color = redisTemplate.opsForList().range("Color", 0, 2);
        for (Object o : color) {
            System.out.println("Color List:" + o);
        }
    }
}

報錯:

Q:RedisTemplate的使用?springboot中

Q:Jedis的使用?spring中

Q:Error:java: 無效的源發行版: 8

A:這是因為模組的target bytecode version和實際的編譯器版本不一致所導致的錯誤,因此要對idea中的project structure 進行 jdk版本設定。

參考

其他:

散列表(Hash table,也叫雜湊表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做散列表 。