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)

猜你喜欢

转载自www.cnblogs.com/iory/p/9138044.html