Redis的基本操作以及info命令


 

Redis性能問題排查解決手冊
Redis的基本操作以及info命令
redis object命令
清理 redis 死鍵

 

1.redis登錄

redis-cli -h 127.0.0.1 -p 6377

2. Redis 配置文件位置查詢

    在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。

 

 

原來掛接在xx下的所有元素被分配到0xx和1xx下。在上圖中,當我們即將遍歷10時,dict進行了rehash,這時,scan命令會從010開始遍歷,而000和100(原00下掛接的元素)不會再被重復遍歷。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM