Redis 幾種寫入方式性能對比


語言平台: Python 2.6

Lib: redis.py (latest)

安裝: 參官網

1. StrictRedis

import redis
r = redis.StrictRedis(host='192.168.0.110', password=pwd, port=6379,db=0)

StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類。

2. Redis

import redis
r = redis.Redis(host='192.168.0.110', password=pwd, port=6379,db=0)

3. 連接池

pool = redis.ConnectionPool(host='host',password='prod', port=6366,db=0)
r = redis.Redis(connection_pool=pool)
pipe = r.pipeline()
pipe.set('one', 'first')
pipe.get(‘one’)
pipe.execute()
for I in xrange(1000000):
    pipe.set(‘GRP1:GRP2:GRP3:Key’+str(i), i)
pipe.execute()

redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認,每個Redis實例都會維護一個自己的連接池。可以直接建立一個連接池,然后作為參數Redis,這樣就可以實現多個Redis實例共享一個連接池.

redis號稱最大能達到10w/s級別set性能。如何達到不詳。不過這里做了一個測試來驗證什么樣的情況下可以達到或者接近官方宣稱的水平。

      ** 運行環境: Opteron 4Core 2.3G/4G RAM/500G disk

下表是本人最近的一個測試結果,供參考。(基於百萬次set操作)

  redis              hiredis                  Redisco                pipeline      多進程+pipeline

  531                 346                         310                   51                     28.9(4x)/23(8x)

  - redis, 原生REDIS連接方式進行單次寫入。

  - hiredis, 官方維護的一份更高性能的redis lib,安裝后即可,不需要引入。

  - 多進程,即設想在數據量比較大的情況下,將插入的隊列平均切割給進程來提高性能

    下表是針對多進程不同數量級和不同進程數下的性能表現。可以看出來,將最小核心執行數量控制在3~4萬次的整數倍之間,能夠達到最好的效率。

指令數

進程數

單進程時間(最大)

單進程時間(最小)

總運行時間

每秒指令數(萬)

每進程指令數

5,000,000

4

02:29.9

02:27.9

02:46.6

3.0

125

5,000,000

8

02:16.6

01:53.2

02:24.1

3.5

62.5

5,000,000

16

01:54.7

01:28.0

02:00.5

4.2

31.25

5,000,000

20

01:51.0

01:17.9

02:00.1

4.2

25

5,000,000

50

01:46.1

00:59.5

02:09.7

3.9

10

5,000,000

100

00:05.6

04:48.6

06:32.0

1.3

5

100,000

4

 

 

00:03.3

3.0

2.5

100,000

2

 

 

00:07.6

1.3

5.0

100,000

1

 

 

00:04.8

2.1

10.0

100,000

8

 

 

00:04.4

2.3

1.3

100,000

3

 

 

00:03.1

3.2

3.3

100,000

16

 

 

00:07.1

1.4

0.6

 

 

  - 結論: 在數量級達到萬以上時,使用連接池方式可以達到20,000次每秒性能。繼續使用多進程的情況下,性能提升2倍以上左右,達到4萬次每秒,若核心越多,速度越高,性能會越好。

  所以,大數據量情況下,1,使用pipeline,   2, 使用多進程, 3, 正確分配數據量給進程, 你將得到單機4w+級別的寫入性能,已經足夠強大了。

  

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import datetime
 4 
 5 def test1(string, cnt):
 6     import redis
 7     r = redis.StrictRedis(host=cfg['host'],password=cfg['pwd'], port=cfg['port'],db=cfg['db'])
 8     now = datetime.datetime.now()
 9     for i in range(0, cnt):
10         r.set(i, string)
11     print datetime.datetime.now() - now
12 
13 def test2(string, cnt):
14     import redisco
15     from redisco.containers import Hash,List,SortedSet,Set
16     r = redisco.connection_setup(host=cfg['host'],password=cfg['pwd'], port=cfg['port'],db=cfg['db'])
17     h = Hash("h")
18     now = datetime.datetime.now()
19     for i in range(0, cnt):
20         h[i] = string
21     print datetime.datetime.now() - now
22 
23 def test3(string, cnt):
24         import redis
25         #redis.ConnectionPool(host=host, password=passwd, port=port, db=db, socket_timeout=3, max_connections=10) # max_connection default 2**31
26         pool = redis.ConnectionPool(host=cfg['host'],password=cfg['pwd'], port=cfg['port'],db=cfg['db'])
27         r = redis.Redis(connection_pool=pool)
28         pipe = r.pipeline()
29         now = datetime.datetime.now()
30         for i in xrange(cnt):
31             pipe.set(i, string)
32         pipe.execute()
33         print datetime.datetime.now() - now
34 
35 def sliceArr(cnt, n):
36         x = []
37         for i in range(n):
38                 x.append((cnt*i/n,cnt*(i+1)/n))
39         return x
40 
41 def test4(q):
42         import redis
43         #redis.ConnectionPool(host=host, password=passwd, port=port, db=db, socket_timeout=3, max_connections=10) # max_connection default 2**31
44         pool = redis.ConnectionPool(host=cfg['host'],password=cfg['pwd'], port=cfg['port'],db=cfg['db'])
45         r = redis.Redis(connection_pool=pool)
46         pipe = r.pipeline()
47         now = datetime.datetime.now()
48         for i in xrange(q[0], q[1]):
49             pipe.set(i, string)
50         pipe.execute()
51         print datetime.datetime.now() - now
52 
53 def test5(string, cnt):
54         from multiprocessing import Pool
55         import subprocess as sub
56         import socket
57         now1 = datetime.datetime.now()
58         n=16
59         #for t in sliceArr(cnt, 4):
60         if 1:
61                 pool = Pool(n)
62                 pool.map(test4, sliceArr(cnt, n))
63                 pool.close()
64                 pool.join()
65         print datetime.datetime.now() - now1
66 
67 if  __name__=="__main__":
68     cfg = {'host':'xxx','pwd':'prod','port':'6366','db':1}
69     string = "0"
70     cnt = 1000000
71     #test1(string, cnt)
72     #test2(string, cnt)
73     #test3(string, cnt)
74     test5(string, cnt)

 


免責聲明!

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



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