redis 消息队列性能测试

redis 消息队列

redis 阻塞list

lpush key value1 value2 ..
brpop key 0

测试环境

  • ubuntu
  • 机器双核4G内存普通机
  • 外网流量4M
  • redis版本: 3.2.6
  • redis 和测试服务程序在一台服务器上
  • 注释了bind:127.0.0.1,
  • maxmemory 3gb
  • 生产消费字符串大小:672byte

测试思路

  • 开启固定数量生产线程进行写操作
  • 开启固定数量的消费线程,进行阻塞消费操作
  • 分别统计固定消息的生产者的吞吐量和消费的者的吞吐量

性能测试

---------write end ------
---------开始时间--------------结束时间-------------写入条数-----使用时间----------吞吐量-----测试运行线程数量---
-2016-12-16 17:35:42---2016-12-16 17:36:20------1000000------38------26315------4
[framework] 2016-12-16 17:36:22,863 - com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler -40656 [redisMq-consumer-i] ERROR com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler  - 
---------开始时间--------------结束时间-----消费消息条数-------花费时间------吞吐量------测试运行线程数量-----
-2016-12-16 17:35:42---2016-12-16 17:36:22------1000001------40------25000------4


---------开始时间--------------结束时间-------------写入条数-----使用时间----------吞吐量-----测试运行线程数量---
-2016-12-16 17:39:09---2016-12-16 17:40:25------2000000------75------26666------4
[framework] 2016-12-16 17:40:29,547 - com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler -79935 [redisMq-consumer-i] ERROR com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler  - 
---------开始时间--------------结束时间-----消费消息条数-------花费时间------吞吐量------测试运行线程数量-----
-2016-12-16 17:39:09---2016-12-16 17:40:29------2000001------79------25316------4

---------write end ------
---------开始时间--------------结束时间-------------写入条数-----使用时间----------吞吐量-----测试运行线程数量---
-2016-12-16 17:43:08---2016-12-16 17:45:03------3000000------114------26315------4
[framework] 2016-12-16 17:45:11,143 - com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler -122312 [redisMq-consumer-i] ERROR com.jiazq.jizq.redis.mq.RedisMqConsumerSchudler  - 
---------开始时间--------------结束时间-----消费消息条数-------花费时间------吞吐量------测试运行线程数量-----
-2016-12-16 17:43:08---2016-12-16 17:45:11------3000001------122------24590------4

结果分析

  • 生产者性能略高于消费者
  • 生产者和消费者的吞吐量都在2.5W以上
  • 高配置的计算机redis性能会更高
  • 适合小型系统消息系统

部分代码

消费者
package com.jiazq.jizq.redis.mq;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.log4j.Logger;


import redis.clients.jedis.Jedis;

public class RedisMqConsumerSchudler {

    private static Logger logger = Logger.getLogger(RedisMqConsumerSchudler.class);

    int threadNumber;

    // 开启时间
    long startTime = 0;

    volatile boolean runState = true;

    AtomicLong count = new AtomicLong(0);

    // 工作线程
    Thread[] workers = null;

    public RedisMqConsumerSchudler (int threadNumber) {

        this.threadNumber = threadNumber;

        workers = new Thread[threadNumber];

        for (int i = 0; i < threadNumber; i++) {
            workers[i] = new Thread(new ReadisConsumeTask(JedisManager.instance().getJedis()));
            workers[i].setDaemon(true);
            workers[i].setName("redisMq-consumer-" + "i");
        }

    }


    /**
     *  启动工作线程
     */
    public void start() {

        for (int i = 0; i < threadNumber; i++) {
            workers[i].start();
        }

        startTime = System.currentTimeMillis();
    }

    class ReadisConsumeTask implements Runnable {

        private Jedis jedis = null;

        ReadisConsumeTask(Jedis jedis) {

            this.jedis = jedis;
        }


        @Override
        public void run() {

            while (runState) {

                try {

                    List<String> strs = jedis.brpop(0,ConfigManager.redis_queue);

                    if (null != strs && strs.size() == 2) {
                        count.addAndGet(1);
                    }

                    if (count.get() == ConfigManager.redis_write_count) {

                        StringBuilder sb = new StringBuilder();
                        SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");

                        long useTime = (new Date().getTime()- startTime)/1000;
                        long throughput = count.get() / useTime;

                        sb.append("\n---------开始时间--------------结束时间-----消费消息条数-------花费时间------吞吐量------测试运行线程数量-----\n");

                        sb.append("-");
                        sb.append(format.format(new Date(startTime)));
                        sb.append("---");
                        sb.append(format.format(new Date()));
                        sb.append("------");
                        sb.append(count.get());
                        sb.append("------");
                        sb.append(useTime);
                        sb.append("------");
                        sb.append(throughput);
                        sb.append("------");
                        sb.append(threadNumber);

                        logger.error(sb.toString());

                        runState = false;
                    }

                } catch (Throwable t) {

                    logger.error("",t);

                    // 连接失败
                    if (!jedis.isConnected()) {

                        //返回连接池里面
                        jedis.close();
                        // 重新获取连接
                        jedis = JedisManager.instance().getJedis();
                    }
                }

            }

        }

    }
}

生产者
package com.jiazq.jizq.redis.mq;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.log4j.Logger;


import redis.clients.jedis.Jedis;

public class RedisMqProduerSchudler {

    private static Logger logger = Logger.getLogger(RedisMqConsumerSchudler.class);

    int threadNumber;

    // 消息计数器
    AtomicLong writeCount = new AtomicLong(ConfigManager.redis_write_count);

    // 开启时间
    long startTime = 0;

    volatile boolean runState = true;

    // 工作线程
    Thread[] workers = null;

    RedisMqProduerSchudler (int threadNumber) {

        this.threadNumber = threadNumber;

        workers = new Thread[threadNumber];

        for (int i = 0; i < threadNumber; i++) {
            workers[i] = new Thread(new RedisProducerTask(JedisManager.instance().getJedis()));
            workers[i].setDaemon(true);
            workers[i].setName("redisMq-consumer-" + "i");
        }
    }


    /**
     *  启动工作线程
     * @throws InterruptedException 
     */
    public void start() throws InterruptedException {

        for (int i = 0; i < threadNumber; i++) {
            workers[i].start();
        }

        startTime = System.currentTimeMillis();

    }


    private static void loopWait(Jedis jedis, long count) throws InterruptedException {

        if (count > ConfigManager.redis_write_count) {

            Thread.sleep(200);

            loopWait(jedis, jedis.llen(ConfigManager.redis_queue));
        }

    }

    class RedisProducerTask implements Runnable {

        private Jedis jedis;

        public RedisProducerTask (Jedis jedis) {

            this.jedis = jedis;
        }



        @Override
        public void run() {

            while (runState) {

                try {

                    long number = writeCount.decrementAndGet();

                    if (runState & number == 0) {
                        runState = false;
                        StringBuilder sb = new StringBuilder();
                        SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");

                        long useTime = ((new Date().getTime() - startTime)/1000);
                        long throughput =( ConfigManager.redis_write_count/useTime);

                        sb.append("\n---------write end ------\n");
                        sb.append("---------开始时间--------------结束时间-------------写入条数-----使用时间----------吞吐量-----测试运行线程数量---\n");

                        sb.append("-");
                        sb.append(format.format(new Date(startTime)));
                        sb.append("---");
                        sb.append(format.format(new Date()));
                        sb.append("------");
                        sb.append(ConfigManager.redis_write_count);
                        sb.append("------");
                        sb.append(useTime);
                        sb.append("------");
                        sb.append(throughput);
                        sb.append("------");

                        sb.append(threadNumber);

                        logger.error(sb.toString());
                        break;
                    } else {

                        long count = jedis.lpush(ConfigManager.redis_queue,
                                ConfigManager.test_string_value);

                        //loopWait(jedis, count);
                    }




                } catch (Throwable t) {

                    logger.error("",t);

                    // 连接失败
                    if (!jedis.isConnected()) {

                        //返回连接池里面
                        jedis.close();
                        // 重新获取连接
                        jedis = JedisManager.instance().getJedis();
                    }
                }

            }

        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值