Redis:降低延迟的通道数。如何防止退化?

时间:2014-10-11 21:10:36

标签: python redis redis-py

pub.py

import redis
import datetime
import time
import json
import sys

import threading
import gevent
from gevent import monkey
monkey.patch_all()

def main(chan):
    redis_host = '10.235.13.29'
    r = redis.client.StrictRedis(host=redis_host, port=6379)
    while True:
        def getpkg():
            package = {'time': time.time(),
                        'signature' : 'content'
                      }

            return package

        #test 2: complex data
        now = json.dumps(getpkg())

        # send it
        r.publish(chan, now)
        print 'Sending {0}'.format(now)
        print 'data type is %s' % type(now)
        time.sleep(1)

def zerg_rush(n):
    for x in range(n):
        t = threading.Thread(target=main, args=(x,))
        t.setDaemon(True)
        t.start()

if __name__ == '__main__':
    num_of_chan = 10
    zerg_rush(num_of_chan)
    cnt = 0
    stop_cnt = 21
    while True:
        print 'Waiting'
        cnt += 1
        if cnt == stop_cnt:
            sys.exit(0)
        time.sleep(30)

sub.py

import redis
import threading
import time
import json
import gevent
from gevent import monkey
monkey.patch_all()

def callback(ind):
    redis_host = '10.235.13.29'
    r = redis.client.StrictRedis(host=redis_host, port=6379)
    sub = r.pubsub()
    sub.subscribe(str(ind))
    start = False
    avg = 0
    tot = 0
    sum = 0
    while True:
        for m in sub.listen():
            if not start:
                start = True
                continue
            got_time = time.time()
            decoded = json.loads(m['data'])
            sent_time = float(decoded['time'])
            dur = got_time - sent_time
            tot += 1
            sum += dur
            avg = sum / tot

            print decoded #'Recieved: {0}'.format(m['data'])
            file_name = 'logs/sub_%s' % ind
            f = open(file_name, 'a')
            f.write('processing no. %s' % tot)
            f.write('it took %s' % dur)
            f.write('current avg: %s\n' % avg)
            f.close()

def zerg_rush(n):
    for x in range(n):
        t = threading.Thread(target=callback, args=(x,))
        t.setDaemon(True)
        t.start()

def main():
    num_of_chan = 10
    zerg_rush(num_of_chan)
    while True:
        print 'Waiting'
        time.sleep(30)

if __name__ == '__main__':
    main()

我正在测试redis pubsub以取代使用rsh与远程盒子进行通信 我测试过的一件事是影响发布和pubsub.listen()延迟的通道数量。

测试:每个频道一个发布者和一个订阅者(发布者每一秒发布一次)。增加通道数量并观察延迟(从发布者发布消息到用户通过侦听获取消息的那一刻的持续时间)

num of chan --------------以秒为单位的平均延迟
10:---------------------------------- 0.004453
50:---------------------------------- 0.005246
100:--------------------------------- 0.0155
200:--------------------------------- 0.0221
300:--------------------------------- 0.0621

注意:在2个CPU + 4GB RAM + 1个NIC RHEL6.4 VM上测试。

  1. 如何通过大量频道维持低延迟?

  2. Redis是单线程的,因此增加更多cpus不会有帮助。也许更多的RAM?如果是这样,还有多少?

  3. 我可以做任何代码或瓶颈的事情都在Redis本身吗?

  4. 也许限制来自我的测试代码用线程编写的方式?

  5. 编辑: Redis Cluster vs ZeroMQ in Pub/Sub, for horizontally scaled distributed systems

    接受的答案说:“我想最大程度地减少延迟。我猜道。频道数量无关紧要。关键因素是发布商数量和订阅者数量,邮件大小,每个发布商每秒的邮件数量,邮件数量每个用户都收到大概的消息。从一个节点到另一个节点,ZeroMQ每秒可以做几百万条小消息;你的瓶颈就是网络很久之前的网络。大多数高容量的pubsub体系结构因此使用类似PGM多播的东西,ZeroMQ支持。“

    从我的测试中,我不知道这是否属实。 (声称频道数量无关紧要)
    例如,我做了一个测试。

    1)一个频道。 100个发布者发布到有1个订阅者收听的频道。发布者一次发布一秒。延迟 0.00965 秒 2)除了1000个发布者之外的相同测试。延迟 0.00808

    现在在我的频道测试期间:
    有1个pub - 1 sub的300个频道导致 0.0621 ,这只有600个连接,低于上述测试但延迟时间显着减慢

0 个答案:

没有答案