1. 程式人生 > >Redis(四)Redis高級

Redis(四)Redis高級

time elements 服務 退出 csv 提升 計算機 無需 incr

一Redis 數據備份與恢復

Redis SAVE 命令用於創建當前數據庫的備份。

語法

redis Save 命令基本語法如下:

redis 127.0.0.1:6379> SAVE 

實例

redis 127.0.0.1:6379> SAVE 
OK

該命令將在 redis 安裝目錄中創建dump.rdb文件。

恢復數據

如果需要恢復數據,只需將備份文件 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可。獲取 redis 目錄可以使用 CONFIG 命令,如下所示:
 
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"

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

Bgsave

創建 redis 備份文件也可以使用命令 BGSAVE,該命令在後臺執行。

實例

127.0.0.1:6379> BGSAVE

Background saving started

二Redis 安全

我們可以通過 redis 的配置文件設置密碼參數,這樣客戶端連接到 redis 服務就需要密碼驗證,這樣可以讓你的 redis 服務更安全。

實例

我們可以通過以下命令查看是否設置了密碼驗證:

127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) ""

默認情況下 requirepass 參數是空的,這就意味著你無需通過密碼驗證就可以連接到 redis 服務。

你可以通過以下命令來修改該參數:

127.0.0.1:6379> CONFIG set requirepass "runoob"
OK
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) "runoob"

設置密碼後,客戶端連接 redis 服務就需要密碼驗證,否則無法執行命令。

語法

AUTH 命令基本語法格式如下:

127.0.0.1:6379> AUTH password

實例127.0.0.1:6379> AUTH "runoob"

OK
127.0.0.1:6379> SET mykey "Test value"
OK
127.0.0.1:6379> GET mykey
"Test value"

三Redis 性能測試

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

語法

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

redis-benchmark [option] [option value]

實例

以下實例同時執行 10000 個請求來檢測性能:

$ redis-benchmark -n 10000  -q

PING_INLINE: 141043.72 requests per second
PING_BULK: 142857.14 requests per second
SET: 141442.72 requests per second
GET: 145348.83 requests per second
INCR: 137362.64 requests per second
LPUSH: 145348.83 requests per second
LPOP: 146198.83 requests per second
SADD: 146198.83 requests per second
SPOP: 149253.73 requests per second
LPUSH (needed to benchmark LRANGE): 148588.42 requests per second
LRANGE_100 (first 100 elements): 58411.21 requests per second
LRANGE_300 (first 300 elements): 21195.42 requests per second
LRANGE_500 (first 450 elements): 14539.11 requests per second
LRANGE_600 (first 600 elements): 10504.20 requests per second
MSET (10 keys): 93283.58 requests per second

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 通過管道傳輸 <numreq> 請求 1
10 -q 強制退出 redis。僅顯示 query/sec 值
11 --csv 以 CSV 格式輸出
12 -l 生成循環,永久執行測試
13 -t 僅運行以逗號分隔的測試命令列表。
14 -I Idle 模式。僅打開 N 個 idle 連接並等待。

實例

以下實例我們使用了多個參數來測試 redis 性能:

$ redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q

SET: 146198.83 requests per second
LPUSH: 145560.41 requests per second

以上實例中主機為 127.0.0.1,端口號為 6379,執行的命令為 set,lpush,請求數為 10000,通過 -q 參數讓結果只顯示每秒執行的請求數。

四Redis 客戶端連接

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

  • 首先,客戶端 socket 會被設置為非阻塞模式,因為 Redis 在網絡事件處理上采用的是非阻塞多路復用模型。
  • 然後為這個 socket 設置 TCP_NODELAY 屬性,禁用 Nagle 算法
  • 然後創建一個可讀的文件事件用於監聽這個客戶端 socket 的數據發送

最大連接數

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

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

config get maxclients

1) "maxclients"
2) "10000"

實例

以下實例我們在服務啟動時設置最大連接數為 100000:

redis-server --maxclients 100000

客戶端命令

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

五Redis 管道技術

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

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

Redis 管道技術

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

實例

查看 redis 管道,只需要啟動 redis 實例並輸入以下命令:

$(echo -en "PING\r\n SET runoobkey redis\r\nGET runoobkey\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379

+PONG
+OK
redis
:1
:2
:3

以上實例中我們通過使用 PING 命令查看redis服務是否可用, 之後我們設置了 runoobkey 的值為 redis,然後我們獲取 runoobkey 的值並使得 visitor 自增 3 次。

在返回的結果中我們可以看到這些命令一次性向 redis 服務提交,並最終一次性讀取所有服務端的響應

管道技術的優勢

管道技術最顯著的優勢是提高了 redis 服務的性能。

一些測試數據

在下面的測試中,我們將使用Redis的Ruby客戶端,支持管道技術特性,測試管道技術對速度的提升效果。

require ‘rubygems‘ 
require ‘redis‘
def bench(descr) 
start = Time.now 
yield 
puts "#{descr} #{Time.now-start} seconds" 
end
def without_pipelining 
r = Redis.new 
10000.times { 
    r.ping 
} 
end
def with_pipelining 
r = Redis.new 
r.pipelined { 
    10000.times { 
        r.ping 
    } 
} 
end
bench("without pipelining") { 
    without_pipelining 
} 
bench("with pipelining") { 
    with_pipelining 
}

從處於局域網中的Mac OS X系統上執行上面這個簡單腳本的數據表明,開啟了管道操作後,往返時延已經被改善得相當低了。

without pipelining 1.185238 seconds 
with pipelining 0.250783 seconds

如你所見,開啟管道後,我們的速度效率提升了5倍。

六Redis 分區

分區是分割數據到多個Redis實例的處理過程,因此每個實例只保存key的一個子集。

分區的優勢

  • 通過利用多臺計算機內存的和值,允許我們構造更大的數據庫。
  • 通過多核和多臺計算機,允許我們擴展計算能力;通過多臺計算機和網絡適配器,允許我們擴展網絡帶寬。

分區的不足

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

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

分區類型

Redis 有兩種類型分區。 假設有4個Redis實例 R0,R1,R2,R3,和類似user:1,user:2這樣的表示用戶的多個key,對既定的key有多種不同方式來選擇這個key存放在哪個實例中。也就是說,有不同的系統來映射某個key到某個Redis服務。

範圍分區

最簡單的分區方式是按範圍分區,就是映射一定範圍的對象到特定的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實例中。註意:取模操作是取除的余數,通常在多種編程語言中用%操作符實現。

七Redis 服務器

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

實例

以下實例演示了如何獲取 redis 服務器的統計信息:

redis 127.0.0.1:6379> INFO
技術分享圖片
# Server
redis_version:2.8.13
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c2238b38b1edb0e2
redis_mode:standalone
os:Linux 3.5.0-48-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.7.2
process_id:3856
run_id:0e61abd297771de3fe812a3c21027732ac9f41fe
tcp_port:6379
uptime_in_seconds:11554
uptime_in_days:0
hz:10
lru_clock:16651447
config_file:

# Clients
connected_clients:1
client-longest_output_list:0
client-biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:589016
used_memory_human:575.21K
used_memory_rss:2461696
used_memory_peak:667312
used_memory_peak_human:651.67K
used_memory_lua:33792
mem_fragmentation_ratio:4.18
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:3
rdb_bgsave_in_progress:0
rdb_last_save_time:1409158561
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats
total_connections_received:24
total_commands_processed:294
instantaneous_ops_per_sec:0
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:41
keyspace_misses:82
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:264

# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:10.49
used_cpu_user:4.96
used_cpu_sys_children:0.00
used_cpu_user_children:0.01

# Keyspace
db0:keys=94,expires=1,avg_ttl=41638810
db1:keys=1,expires=0,avg_ttl=0
db3:keys=1,expires=0,avg_ttl=0
View Code

下表列出了 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)的內部命令

八Java 使用 Redis

安裝

開始在 Java 中使用 Redis 前, 我們需要確保已經安裝了 redis 服務及 Java redis 驅動,且你的機器上能正常使用 Java。 Java的安裝配置可以參考我們的 Java開發環境配置 接下來讓我們安裝 Java redis 驅動:

  • 首先你需要下載驅動包 下載 jedis.jar,確保下載最新驅動包。
  • 在你的 classpath 中包含該驅動包。

本站提供了 2.9.0 jar 版本下載: jedis-2.9.0.jar

連接到 redis 服務

實例

import redis.clients.jedis.Jedis; 

public class RedisJava {
public static void main(String[] args) {
//連接本地的 Redis 服務
Jedis jedis = new Jedis("localhost");
System.out.println("連接成功");
//查看服務是否運行
System.out.println("服務正在運行: "+jedis.ping());
}
}

編譯以上 Java 程序,確保驅動包的路徑是正確的。

連接成功
服務正在運行: PONG

Redis Java String(字符串) 實例

實例

import redis.clients.jedis.Jedis; 

public class RedisStringJava { 
    public static void main(String[] args) { 
     //連接本地的 Redis 服務 
     Jedis jedis = new Jedis("localhost"); 
     System.out.println("連接成功"); 
     //設置 redis 字符串數據 
     jedis.set("runoobkey", "www.runoob.com");
      // 獲取存儲的數據並輸出 
     System.out.println("redis 存儲的字符串為: "+jedis.get("runoobkey"));
}
}

編譯以上程序。

連接成功
redis 存儲的字符串為: www.runoob.com

Redis Java List(列表) 實例

實例

import java.util.List;
import redis.clients.jedis.Jedis; 

public class RedisListJava {
     public static void main(String[] args) { 
     //連接本地的 Redis 服務 
     Jedis jedis = new Jedis("localhost");
     System.out.println("連接成功"); 
     //存儲數據到列表中 
     jedis.lpush("site-list", "Runoob");
     jedis.lpush("site-list", "Google");
     jedis.lpush("site-list", "Taobao"); 
     // 獲取存儲的數據並輸出 
     List<String> list = jedis.lrange("site-list", 0 ,2); 
        for(int i=0; i<list.size(); i++) {
             System.out.println("列表項為: "+list.get(i)); 
        } 
    } 
}

編譯以上程序。

連接成功
列表項為: Taobao
列表項為: Google
列表項為: Runoob

Redis Java Keys 實例

實例

import java.util.Iterator; 
import java.util.Set; 
import redis.clients.jedis.Jedis; 

public class RedisKeyJava { 
      public static void main(String[] args) { 
      //連接本地的 Redis 服務 
      Jedis jedis = new Jedis("localhost"); 
      System.out.println("連接成功"); 
      // 獲取數據並輸出 
      Set<String> keys = jedis.keys("*"); 
      Iterator<String> it=keys.iterator() ; 
           while(it.hasNext()){ 
               String key = it.next(); 
               System.out.println(key); 
           }
      } 
 }

編譯以上程序。

連接成功

runoobkey

site-list

Redis(四)Redis高級