最近測試服務端的時候,接觸到了redis,之前也看過,但不系統,藉著這次實踐,記錄一下。 一、寫在前面 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 它通常被稱為數據結構伺服器,因為值(va ...
最近測試服務端的時候,接觸到了redis,之前也看過,但不系統,藉著這次實踐,記錄一下。
一、寫在前面
Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。
它通常被稱為數據結構伺服器,因為值(value)可以是 字元串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。
使用場景和優勢簡單概述:
1.redis是目前業界非常受到歡迎的一個記憶體資料庫,一般用作系統的中間緩存系統,用以提升整體商業系統的吞吐量和響應速度;
2.redis支持從記憶體中實現數據的讀寫,所以速度非常快;
3.redis支持數據持久化,redis將數據存儲在硬碟中,即使斷電了,redis依然可以將數據重新載入到記憶體中。
二、安裝redis
windows、linux系統下安裝redis的詳細教程可以見此鏈接:
http://www.runoob.com/redis/redis-install.html
下載完之後,進行解壓、安裝:
解壓命令:tar -zxvf redis-3.2.11.tar.gz
解壓得到一個【redis-3.2.11】文件夾,進入到此文件夾內;
Linux系統安裝步驟:
1.輸入指令:make,進行編譯,編譯完成之後,會看到:
然後cd到src目錄
2.執行make install,進行安裝
make install PREFIX=/usr/local/redis #安裝到指定目錄中
如果make失敗,一般是你們系統中還未安裝gcc或者tcl(根據具體的報錯信息安裝),那麼可以通過yum安裝:
yum install gcc/tcl
安裝完成後,繼續執行make
在安裝redis成功後,可以在/usr/local/redis看到一個bin的目錄,裡面包括了以下文件:
redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server
測試安裝是否成功
[root@docker redis-3.2.11]# make test
只截取最後的結果:
\o/ All tests passed without errors!
Cleanup: may take some time... OK
配置redis.conf:
[root@docker redis-3.2.11]# vi /usr/local/src/redis-3.2.11/redis.conf
我這裡修改3個地方
A. daemonize no 改成 daemonize yes (將redis修改為後臺啟動進程,防止redis啟動後一直停留在redis界面)
B. logfile "" 改成 logfile "./redis.log"(redis日誌文件,在redis.conf同級目錄下)
C. bind 127.0.0.1 (只能本機訪問) 改為 bind 0.0.0.0 (非本機亦可訪問(或者可以綁定指定IP))
啟動redis:
[root@docker ~]# redis-server /usr/local/src/redis-3.2.11/redis.conf
這裡載入剛纔修改的預設的redis配置文件redis.conf
查看是否啟動成功:
[root@docker ~]# ps -ef | grep redis
root 30284 1 0 16:48 ? 00:00:00 redis-server 127.0.0.1:6379
root 30289 25916 0 16:48 pts/0 00:00:00 grep redis
測試redis:
[root@docker ~]# redis-cli
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> get foo
"bar"
127.0.0.1:6379> exit
關閉redis:
[root@docker redis-3.2.11]# redis-cli shutdown
redis安全模式訪問:
測試程式報錯為:
DENIED Redis is running protected mode because protected mode is enabled,
no bind address was specified, no authentication password is requested to clients.
In this mode connections are only accepted from the loopback interface.
需要給redis配置密碼
啟動redis客戶端
執行 redis-cli指令
然後執行 config set requirepass 777888(密碼)
三、redis測試
1.簡單的Redis測試程式:
可以自行創建Eclipse項目,引入jedis的客戶端包,測試程式如下:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;
1 public class RedisTest {
2
3 private Jedis jedis = null;
4 private String key1 = "key1";
5 private String key2 = "key2";
6
7 public RedisTest() {
8 jedis = new Jedis("127.0.0.1"); // redis的IP地址
9 jedis.auth("redis"); // redis密碼
10 }
11
12 public static void main(String[] args) {
13 RedisTest redisTest = new RedisTest();
14 redisTest.isReachable(); // redis是否訪問成功 返回結果true/false
15 redisTest.testData(); // 數據測試
16 redisTest.delData(); // 刪除數據
17 redisTest.testExpire();
18 }
19
20 public boolean isReachable() {
21 boolean isReached = true;
22 try {
23 jedis.connect();
24 jedis.ping();
25 // jedis.quit();
26 } catch (JedisConnectionException e) {
27 e.printStackTrace();
28 isReached = false;
29 }
30
31 System.out
32 .println("The current Redis Server is Reachable:" + isReached);
33 return isReached;
34 }
35
36 public void testData() {
37 jedis.set("key1", "data1");
38 jedis.set("maxm", "MMM");
39 System.out.println(jedis.get("maxm"));
40 System.out.println("Check status of data existing:"
41 + jedis.exists(key1));
42 System.out.println("Get Data key1:" + jedis.get("key1"));
43
44 long s = jedis.sadd(key2, "data2");
45 System.out.println("Add key2 Data:" + jedis.scard(key2)
46 + " with status " + s);
47 }
48
49 public void delData() {
50 long count = jedis.del(key1);
51
52 System.out.println("Get Data Key1 after it is deleted:"
53 + jedis.get(key1));
54 }
55
56 public void testExpire() {
57 long count = jedis.expire(key2, 5);
58
59 try {
60 Thread.currentThread().sleep(6000);
61 } catch (InterruptedException e) {
62 e.printStackTrace();
63 }
64
65 if (jedis.exists(key2)) {
66 System.out
67 .println("Get Key2 in Expire Action:" + jedis.scard(key2));
68 } else {
69 System.out.println("Key2 is expired with value:"
70 + jedis.scard(key2));
71 }
72 }
73
74 }
2.Redis性能壓測工具 redis-benchmark
Redis 自帶了一個叫 redis-benchmark
的工具來模擬 N 個客戶端同時發出 M 個請求。 (類似於 Apache ab 程式)。你可以使用 redis-benchmark -h 來查看基準參數。
以下參數被支持:
Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]
-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-s <socket> Server socket (overrides host and port)
-a <password> Password for Redis Auth
-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 100000)
-d <size> Data size of SET/GET value in bytes (default 2)
-dbnum <db> SELECT the specified db number (default 0)
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will expand the string __rand_int__
inside an argument with a 12 digits number in the specified range
from 0 to keyspacelen-1. The substitution changes every time a command
is executed. Default tests use this to hit random keys in the
specified range.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values
--csv Output in CSV format
-l Loop. Run the tests forever
-t <tests> Only run the comma separated list of tests. The test
names are the same as the ones produced as output.
-I Idle mode. Just open N idle connections and wait.
測試命令事例:
1、redis-benchmark -h 192.168.1.201 -p 6379 -c 100 -n 100000
100個併發連接,100000個請求,檢測host為localhost 埠為6379的redis伺服器性能
2、redis-benchmark -h 192.168.1.201 -p 6379 -q -d 100
測試存取大小為100位元組的數據包的性能
3、redis-benchmark -t set,lpush -n 100000 -q
只測試某些操作的性能
4、redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"
只測試某些數值存取的性能
requests completed in 0.30 seconds
parallel clients
bytes payload
keep alive: 1
0.11% <= 1 milliseconds
86.00% <= 2 milliseconds
90.12% <= 3 milliseconds
96.68% <= 4 milliseconds
99.27% <= 5 milliseconds
99.54% <= 6 milliseconds
99.69% <= 7 milliseconds
99.78% <= 8 milliseconds
99.89% <= 9 milliseconds
100.00% <= 9 milliseconds
33222.59 requests per second
====== PING_BULK ======
requests completed in 0.27 seconds
parallel clients
bytes payload
keep alive: 1
0.93% <= 1 milliseconds
97.66% <= 2 milliseconds
100.00% <= 2 milliseconds
37174.72 requests per second
====== SET ======
requests completed in 0.32 seconds
parallel clients
bytes payload
keep alive: 1
0.22% <= 1 milliseconds
91.68% <= 2 milliseconds
97.78% <= 3 milliseconds
98.80% <= 4 milliseconds
99.38% <= 5 milliseconds
99.61% <= 6 milliseconds
99.72% <= 7 milliseconds
99.83% <= 8 milliseconds
99.94% <= 9 milliseconds
100.00% <= 9 milliseconds
30959.75 requests per second
====== GET ======
requests completed in 0.28 seconds
parallel clients
bytes payload
keep alive: 1
0.55% <= 1 milliseconds
98.86% <= 2 milliseconds
100.00% <= 2 milliseconds
35971.22 requests per second
====== INCR ======
requests completed in 0.14 seconds
parallel clients
bytes payload
keep alive: 1
95.61% <= 1 milliseconds
100.00% <= 1 milliseconds
69444.45 requests per second
====== LPUSH ======
requests completed in 0.21 seconds
parallel clients
bytes payload
keep alive: 1
18.33% <= 1 milliseconds
100.00% <= 1 milliseconds
48309.18 requests per second
====== LPOP ======
requests completed in 0.23 seconds
parallel clients
bytes payload
keep alive: 1
0.29% <= 1 milliseconds
99.76% <= 2 milliseconds
100.00% <= 2 milliseconds
44052.86 requests per second
====== SADD ======
requests completed in 0.22 seconds
parallel clients
bytes payload
keep alive: 1
2.37% <= 1 milliseconds
99.81% <= 2 milliseconds
100.00% <= 2 milliseconds
44444.45 requests per second
====== SPOP ======
requests completed in 0.22 seconds
parallel clients
bytes payload
keep alive: 1
4.27% <= 1 milliseconds
99.84% <= 2 milliseconds
100.00% <= 2 milliseconds
44642.86 requests per second
====== LPUSH (needed to benchmark LRANGE) ======
requests completed in 0.22 seconds
parallel clients
bytes payload
keep alive: 1
12.35% <= 1 milliseconds
99.62% <= 2 milliseconds
100.00% <= 2 milliseconds
46082.95 requests per second
====== LRANGE_100 (first 100 elements) ======
requests completed in 0.48 seconds
parallel clients
bytes payload
keep alive: 1
0.01% <= 1 milliseconds
3.27% <= 2 milliseconds
98.71% <= 3 milliseconds
99.93% <= 4 milliseconds
100.00% <= 4 milliseconds
20964.36 requests per second
====== LRANGE_300 (first 300 elements) ======
requests completed in 1.26 seconds
parallel clients
bytes payload
keep alive: 1
0.01% <= 2 milliseconds
0.14% <= 3 milliseconds
0.90% <= 4 milliseconds
7.03% <= 5 milliseconds
31.68% <= 6 milliseconds
78.93% <= 7 milliseconds
98.88% <= 8 milliseconds
99.56% <= 9 milliseconds
99.72% <= 10 milliseconds
99.95% <= 11 milliseconds
100.00% <= 11 milliseconds
7961.78 requests per second
====== LRANGE_500 (first 450 elements) ======
requests completed in 1.82 seconds
parallel clients
bytes payload
keep alive: 1
0.01% <= 2 milliseconds
0.06% <= 3 milliseconds
0.14% <= 4 milliseconds
0.30% <= 5 milliseconds
0.99% <= 6 milliseconds
2.91% <= 7 milliseconds
8.11% <= 8 milliseconds
43.15% <= 9 milliseconds
88.38% <= 10 milliseconds
97.25% <= 11 milliseconds
98.61% <= 12 milliseconds
99.26% <= 13 milliseconds
99.30% <= 14 milliseconds
99.44% <= 15 milliseconds
99.48% <= 16 milliseconds
99.64% <= 17 milliseconds
99.85% <= 18 milliseconds
99.92% <= 19 milliseconds
99.95% <= 20 milliseconds
99.96% <= 21 milliseconds
99.97% <= 22 milliseconds
100.00% <= 23 milliseconds
5491.49 requests per second
====== LRANGE_600 (first 600 elements) ======
requests completed in 2.29 seconds
parallel clients
bytes payload
keep alive: 1
0.01% <= 2 milliseconds
0.05% <= 3 milliseconds
0.10% <= 4 milliseconds
0.19% <= 5 milliseconds
0.34% <= 6 milliseconds
0.46% <= 7 milliseconds
0.58% <= 8 milliseconds
4.46% <= 9 milliseconds
21.80% <= 10 milliseconds
40.48% <= 11 milliseconds
60.14% <= 12 milliseconds
79.81% <= 13 milliseconds
93.77% <= 14 milliseconds
97.14% <= 15 milliseconds
98.67% <= 16 milliseconds
99.08% <= 17 milliseconds
99.30% <= 18 milliseconds
99.41% <= 19 milliseconds
99.52% <= 20 milliseconds
99.61% <= 21 milliseconds
99.79% <= 22 milliseconds
99.88% <= 23 milliseconds
99.89% <= 24 milliseconds
99.95% <= 26 milliseconds
99.96% <= 27 milliseconds
99.97% <= 28 milliseconds
99.98% <= 29 milliseconds
100.00% <= 29 milliseconds
4359.20 requests per second
====== MSET (10 keys) ======
requests completed in 0.37 seconds
parallel clients
bytes payload
keep alive: 1
0.01% <= 1 milliseconds
2.00% <= 2 milliseconds
18.41% <= 3 milliseconds
88.55% <= 4 milliseconds
96.09% <= 5 milliseconds
99.50% <= 6 milliseconds
99.65% <= 7 milliseconds
99.75% <= 8 milliseconds
99.77% <= 9 milliseconds
99.78% <= 11 milliseconds
99.79% <= 12 milliseconds
99.80% <= 13 milliseconds
99.81% <= 15 milliseconds
99.82% <= 16 milliseconds
99.83% <= 17 milliseconds
99.84% <= 19 milliseconds
99.85% <= 21 milliseconds
99.86% <= 23 milliseconds
99.87% <= 24 milliseconds
99.88% <= 25 milliseconds
99.89% <= 27 milliseconds
99.90% <= 28 milliseconds
99.91% <= 30 milliseconds
99.92% <= 32 milliseconds
99.93% <= 34 milliseconds
99.95% <= 35 milliseconds
99.96% <= 36 milliseconds
99.97% <= 37 milliseconds
99.98% <= 39 milliseconds
99.99% <= 41 milliseconds
100.00% <= 41 milliseconds
27173.91 requests per second
更詳細的使用方法可以參加鏈接:
http://www.redis.cn/topics/benchmarks.html
-------------------------------------------
-------------------------------------------
***番外篇***:
一、將redis做成一個服務
複製腳本到/etc/rc.d/init.d目錄
ps: /etc/rc.d/init.d/目錄下的腳本就類似與windows中的註冊表,在系統啟動的時候某些指定腳本將被執行
其服務腳本位於:
/usr/local/src/redis/utils/redis_init_script
必須將其複製到/etc/rc.d/init.d的目錄下:
cp /usr/local/src/redis/utils/redis_init_script /etc/rc.d/init.d/redis
將redis_init_script複製到/etc/rc.d/init.d/,同時易名為redis。
如果這時添加註冊服務:
chkconfig --add redis
將報以下錯誤:
redis服務不支持chkconfig
為此,需要更改redis腳本。
2.更改redis腳本
打開使用vi打開腳本,查看腳本信息:
vim /etc/rc.d/init.d/redis
看到的內容如下(下內容是更改好的信息):
1 #!/bin/sh
2 #chkconfig: 2345 80 90
3 # Simple Redis init.d script conceived to work on Linux systems
4 # as it does use of the /proc filesystem.
5
6 REDISPORT=6379
7 EXEC=/usr/local/redis/bin/redis-server
8 CLIEXEC=/usr/local/redis/bin/redis-cli
9
10 PIDFILE=/var/run/redis_${REDISPORT}.pid
11 CONF="/etc/redis/${REDISPORT}.conf"
12
13 case "$1" in
14 start)
15 if [ -f $PIDFILE ]
16 then
17 echo "$PIDFILE exists, process is already running or crashed"
18 else
19 echo "Starting Redis server..."
20 $EXEC $CONF &
21 fi
22 ;;
23 stop)
24 if [ ! -f $PIDFILE ]
25 then
26 echo "$PIDFILE does not exist, process is not running"
27 else
28 PID=$(cat $PIDFILE)
29 echo "Stopping ..."
30 $CLIEXEC -p $REDISPORT shutdown
31 while [ -x /proc/${PID} ]
32 do
33 echo "Waiting for Redis to shutdown ..."
34 sleep 1
35 done
36 echo "Redis stopped"
37 fi
38 ;;
39 *)
40 echo "Please use start or stop as first argument"
41 ;;
42 esac
和原配置文件相比:
1.新增了第2行的內容
#chkconfig: 2345 80 90
2.原文件EXEC、CLIEXEC參數,有所更改。
EXEC=/usr/local/redis/bin/redis-server
CLIEXEC=/usr/local/redis/bin/redis-cli
3.redis開啟的命令,以後臺運行的方式執行。
$EXEC $CONF &
ps:註意後面的那個“&”,即是將服務轉到後面運行的意思,否則啟動服務時,Redis服務將
占據在前臺,占用了主用戶界面,造成其它的命令執行不了。
4.將redis配置文件拷貝到/etc/redis/${REDISPORT}.conf
mkdir /etc/redis
cp /usr/local/src/redis/redis.conf /etc/redis/6379.conf
這樣,redis服務腳本指定的CONF就存在了。預設情況下,Redis未啟用認證,可以通過開啟6379.conf的requirepass 指定一個驗證密碼。
以上操作完成後,即可註冊yedis服務:
chkconfig --add redis
5.啟動redis服務
service redis start
二、將Redis的命令所在目錄添加到系統參數PATH中 (添加環境變數)
修改profile文件:
vi /etc/profile
在最後行追加:
export PATH="$PATH:/usr/local/redis/bin"
然後馬上應用這個文件:
. /etc/profile
這樣就可以直接調用redis-cli的命令了,如下所示:
1 $ redis-cli
2 redis 127.0.0.1:6379> auth superman
3 OK
4 redis 127.0.0.1:6379> ping
5 PONG
6 redis 127.0.0.1:6379>
---------------------------------------------
本文引用借鑒了其他已發表的文章。