天天看點

Redis的基本操作以及info指令

    在redis内部執行指令: CONFIG GET * 

    一般情況下配置檔案叫:redis.conf

3. 查詢Redis程序

ps -ef | grep redis-server 可以檢視 redis程序,以及可以檢視到安裝路徑等資訊

4. redis key值擷取

    keys * 擷取目前資料下所有KEY值

    get  key  

  select 2 切換到第二個資料庫

5. info指令

    轉自:http://www.runoob.com/redis/server-info.html

    info server   :  一般 Redis 伺服器資訊,包含以下域:

  •  redis_version : Redis 伺服器版本
  • redis_git_sha1 : Git SHA1
  • redis_git_dirty : Git dirty flag
  • os : Redis 伺服器的宿主作業系統 arch_bits : 架構(32 或 64 位)
  • multiplexing_api : Redis 所使用的事件處理機制
  • gcc_version : 編譯 Redis 時所使用的 GCC 版本
  • process_id : 伺服器程序的 PID
  • run_id : Redis 伺服器的随機辨別符(用于 Sentinel 和叢集)
  • tcp_port : TCP/IP 監聽端口 uptime_in_seconds : 自 Redis 伺服器啟動以來,經過的秒數
  • uptime_in_days : 自 Redis 伺服器啟動以來,經過的天數
  • lru_clock : 以分鐘為機關進行自增的時鐘,用于 LRU 管理

    info clients      表示已連接配接用戶端資訊 包含以下内容:

  • connected_clients           已連接配接用戶端的數量(不包括通過從屬伺服器連接配接的用戶端)
  • client_longest_output_list        目前連接配接的用戶端當中,最長的輸出清單
  • client_longest_input_buf          目前連接配接的用戶端當中,最大輸入緩存
  • blocked_clients            正在等待阻塞指令(BLPOP、BRPOP、BRPOPLPUSH)的用戶端的數量

  info cpu    CPU 計算量統計資訊

     info mem 記憶體資訊,包含以下:

  • used_memory : 由 Redis 配置設定器配置設定的記憶體總量,以位元組(byte)為機關
  • used_memory_human : 以人類可讀的格式傳回 Redis 配置設定的記憶體總量
  • used_memory_rss : 從作業系統的角度,傳回 Redis 已配置設定的記憶體總量(俗稱常駐集大小)。這個值和 top 、 ps 等指令的輸出一緻。
  • used_memory_peak : Redis 的記憶體消耗峰值(以位元組為機關)
  • used_memory_peak_human : 以人類可讀的格式傳回 Redis 的記憶體消耗峰值
  • used_memory_lua : Lua 引擎所使用的記憶體大小(以位元組為機關)
  • mem_fragmentation_ratio : used_memory_rss 和 used_memory 之間的比率 記憶體碎片率
  • mem_allocator : 在編譯時指定的, Redis 所使用的記憶體配置設定器。可以是 libc 、 jemalloc 或者 tcmalloc 。

    在理想情況下, used_memory_rss 的值應該隻比 used_memory 稍微高一點兒。

    當 rss > used ,且兩者的值相差較大時,表示存在(内部或外部的)記憶體碎片。

    記憶體碎片的比率可以通過 mem_fragmentation_ratio 的值看出。

    當 used > rss 時,表示 Redis 的部分記憶體被作業系統換出到交換空間了,在這種情況下,操作可能會産生明顯的延遲。--名額

    當 Redis 釋放記憶體時,配置設定器可能會,也可能不會,将記憶體返還給作業系統。

    如果 Redis 釋放了記憶體,卻沒有将記憶體返還給作業系統,那麼 used_memory 的值可能和作業系統顯示的 Redis 記憶體占用并不一緻。

    檢視 used_memory_peak 的值可以驗證這種情況是否發生

  info persistence     RDB 和 AOF 的相關資訊

  info stats : 一般統計資訊

  info replication : 主/從複制資訊

  info commandstats    Redis 指令統計資訊

  info cluster    Redis 叢集資訊

  info keyspace     redis 資料庫相關的統計資訊

6. redis慢查詢語句

slow log get 10    慢查詢語句, 在上一個節中有講過

     http://www.cnblogs.com/huamei2008/p/8850047.html

7.redis查詢延時

Redis-cli --latency

8.  Redis自身性能壓測

   指令:

  redis-benchmark -p 6379 -c 20000 -n 50000

    -h 表示IP

    -p 表示端口

    -c 表示連接配接數

    -n表示請求數

    -t 後面跟請求方式, 如get

9.scan指令

有時,我們需要針對符合條件的一部分指令進行操作,比如删除以test_開頭的key。那麼怎麼擷取到這些key呢?在Redis2.8版本之前,我們可以使用keys指令按照正則比對得到我們需要的key。但是這個指令有兩個缺點:

  1. 沒有limit,我們隻能一次性擷取所有符合條件的key,如果結果有上百萬條,那麼等待你的就是“無窮無盡”的字元串輸出。
  2. keys指令是周遊算法,時間複雜度是O(N)。如我們剛才所說,這個指令非常容易導緻Redis服務卡頓。是以,我們要盡量避免在生産環境使用該指令。

在滿足需求和存在造成Redis卡頓之間究竟要如何選擇呢?面對這個兩難的抉擇,Redis在2.8版本給我們提供了解決辦法——scan指令。

相比于keys指令,scan指令有兩個比較明顯的優勢:

  1. scan指令的時間複雜度雖然也是O(N),但它是分次進行的,不會阻塞線程。
  2. scan指令提供了limit參數,可以控制每次傳回結果的最大條數。

這兩個優勢就幫助我們解決了上面的難題,不過scan指令也并不是完美的,它傳回的結果有可能重複,是以需要用戶端去重。至于為什麼會重複,相信你看完本文之後就會有答案了。

關于scan指令的基本用法,可以參看Redis指令詳解:Keys一文中關于SCAN指令的介紹。

今天我們主要從底層的結構和源碼的角度來讨論scan是如何工作的。

Redis的結構

Redis使用了Hash表作為底層實作,原因不外乎高效且實作簡單。說到Hash表,很多Java程式員第一反應就是HashMap。沒錯,Redis底層key的存儲結構就是類似于HashMap那樣數組+連結清單的結構。其中第一維的數組大小為2n(n>=0)。每次擴容數組長度擴大一倍。

scan指令就是對這個一維數組進行周遊。每次傳回的遊标值也都是這個數組的索引。limit參數表示周遊多少個數組的元素,将這些元素下挂接的符合條件的結果都傳回。因為每個元素下挂接的連結清單大小不同,是以每次傳回的結果數量也就不同。

SCAN的周遊順序

關于scan指令的周遊順序,我們可以用一個小栗子來具體看一下。

127.0.0.1:6379> keys *
1) "db_number"
2) "key1"
3) "myKey"
127.0.0.1:6379> scan 0 MATCH * COUNT 1
1) "2"
2) 1) "db_number"
127.0.0.1:6379> scan 2 MATCH * COUNT 1
1) "1"
2) 1) "myKey"
127.0.0.1:6379> scan 1 MATCH * COUNT 1
1) "3"
2) 1) "key1"
127.0.0.1:6379> scan 3 MATCH * COUNT 1
1) "0"
2) (empty list or set)           

我們的Redis中有3個key,我們每次隻周遊一個一維數組中的元素。如上所示,SCAN指令的周遊順序是

0->2->1->3

這個順序看起來有些奇怪。我們把它轉換成二進制就好了解一些了。

00->10->01->11

我們發現每次這個序列是高位加1的。普通二進制的加法,是從右往左相加、進位。而這個序列是從左往右相加、進位的。這一點我們在redis的源碼中也得到印證。

在dict.c檔案的dictScan函數中對遊标進行了如下處理

v = rev(v);
v++;
v = rev(v);           

意思是,将遊标倒置,加一後,再倒置,也就是我們所說的“高位加1”的操作。

這裡大家可能會有疑問了,為什麼要使用這樣的順序進行周遊,而不是用正常的0、1、2……這樣的順序呢,這是因為需要考慮周遊時發生字典擴容與縮容的情況(不得不佩服開發者考慮問題的全面性)。

我們來看一下在SCAN周遊過程中,發生擴容時,周遊會如何進行。加入我們原始的數組有4個元素,也就是索引有兩位,這時需要把它擴充成3位,并進行rehash。

Redis的基本操作以及info指令

原來挂接在xx下的所有元素被配置設定到0xx和1xx下。在上圖中,當我們即将周遊10時,dict進行了rehash,這時,scan指令會從010開始周遊,而000和100(原00下挂接的元素)不會再被重複周遊。

再來看看縮容的情況。假設dict從3位縮容到2位,當即将周遊110時,dict發生了縮容,這時scan會周遊10。這時010下挂接的元素會被重複周遊,但010之前的元素都不會被重複周遊了。是以,縮容時還是可能會有些重複元素出現的。