redis書き込み操作性能試験(単機)

61872 ワード

redis書き込み操作性能テスト(スタンドアロン版)
テストの目的
  • 熟知jedis操作redis
  • redis大量書き込み操作性能指標に大まかな認知がある
  • テスト環境
  • ubuntu
  • マシンデュアルコア4 Gメモリ普通機
  • 外部ネットワークトラフィック4 M
  • redisバージョン:3.2.6
  • redisとテストサービスプログラムは1台のサーバ上
  • redis構成
  • パスワードの追加
  • bind:127.0.0.1,
  • maxmemory 3gb

  • 問題にぶつかる
    問題1
    更に300万のデータを挿入する時、間違いを報告します
    // redis     
    2670:M 13 Dec 17:30:53.061 * 10 changes in 300 seconds. Saving...
    2670:M 13 Dec 17:30:53.061 # Can't save in background: fork: Cannot allocate memory
    
    // redis-cli 
    127.0.0.1:6379> 
    127.0.0.1:6379> flushdb
    (error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
    127.0.0.1:6379

    解決策
    //    http://www.cnblogs.com/qq78292959/p/3994341.html
    
               fork,       ,            G    ,fork           。   16G      fork 14G      ?           。     ,          fork    ,fork                  。
    
          ,        vm.overcommit_memory = 1
    
    Linux       vm.overcommit_memory           。
    
    1.    vm.overcommit_memory = 12.vm.overcommit_memory = 0swap,      。
    3.vm.overcommit_memory = 2swap,      。
    
    
    Arch linux  vm.overcommit_memory   
             
    
     /etc/sysctl.conf0
    
    vm.overcommit_memory = 0
    
          
    
    #sysctl -p
    
    

    テストの考え方
    redisに対してそれぞれ100万200万300万データ量の挿入を行い,それぞれにかかった時間を統計する.
    テスト結果
    ログ情報
    ====================================================
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 16:56:22---2016-12-13 16:56:44------1000000------21791------45890-----------4-----------11472--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 17:15:23---2016-12-13 17:16:07------2000000------43802------45660-----------4-----------11415--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:23:47---2016-12-13 18:24:57------3000000------70256------42700-----------4-----------10675--------748byte-----
    
    
    --------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:33:53---2016-12-13 18:34:21------1000000------28133------35545-----------2-----------17772--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:31:34---2016-12-13 18:32:32------2000000------57970------34500-----------2-----------17250--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:27:37---2016-12-13 18:29:02------3000000------85097------35253-----------2-----------17626--------748byte-----
    
    
    
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:36:01---2016-12-13 18:36:21------1000000------20085------49788-----------6-----------8298--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:37:43---2016-12-13 18:38:25------2000000------41571------48110-----------6-----------8018--------748byte-----
    ---------    --------------    -------------    -----    (  )-----   --------        --------       -------       
    -2016-12-13 18:39:25---2016-12-13 18:40:30------3000000------65840------45565-----------6-----------7594--------748byte-----
    
    
    

    結果分析
  • 100万件データ(700 M)redis挿入最低時間20 s、200万件データ最低41秒300万件データ最低65秒
  • 200万データ以下、データ挿入効率相当、300万本効率実行効率低下
  • 最高redis挿入スループットは4.9 W/S
  • シングルスレッドクライアント最高スループット1.7 W/S
  • 結論
    300万件の実行効率が低下し、RDBのデフォルトポリシーと関係がある.
    save 900 1
    save 300 10
    save 60 10000
    
  • 今回の試験ではredis性能のピークには達しなかったが,5 W/Sでの同時スループットを維持した.シングルクライアントスレッド最低1.7 W/S.
  • 以前のredis読み取り性能試験と比較して、redis読み取り効率は書き込みの1.4倍である.

  • テストコード
    package com.jiazq.jizq.redis.mq;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicLong;
    
    import org.apache.log4j.Logger;
    
    
    import redis.clients.jedis.Jedis;
    
    public class RedisWriteTaskSchudler {
    
        private static Logger logger = Logger.getLogger(RedisWriteTaskSchudler.class);
    
        volatile boolean runState = true;
    
        //     
        long startTime = 0;
    
        long endTime = 0;
    
        //     
        Thread[] workers = null;
    
        //     
        int threadNumber = 0;
    
        AtomicLong writeCount = new AtomicLong(ConfigManager.redis_write_count);
    
        //       
        public Semaphore semaphore = new Semaphore(1);
    
        //    
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
    
    
    
        RedisWriteTaskSchudler (int threadNumber) {
    
            //              2 
            this.threadNumber = threadNumber;
    
            workers = new Thread[threadNumber];
    
            for (int i = 0; i < threadNumber; i++) {
                workers[i] = new Thread(new RedisWriteTask(JedisManager.instance().getJedis()));
                workers[i].setDaemon(true);
                workers[i].setName(ConfigManager.read_thread_name + "i");
            }
    
            executorService.scheduleAtFixedRate(new PrintTimer(), 2, 15, TimeUnit.SECONDS);
    
        }
    
        class PrintTimer implements Runnable {
    
            @Override
            public void run() {
    
                //   
                if (runState == false) {
    
                    JedisManager.instance().shutdown();
    
                    executorService.shutdown();
                }
            }
    
        }
    
        /**
         *        
         * @throws InterruptedException 
         */
        public void start() throws InterruptedException {
    
            for (int i = 0; i < threadNumber; i++) {
                workers[i].start();
            }
    
            startTime = System.currentTimeMillis();
    
        }
    
    
        /**
         *     
         */
        public void shutdown() {
            runState = false;
            executorService.shutdown();
        }
    
        public synchronized void log() {
    
            if (endTime == 0) {
    
                endTime = System.currentTimeMillis();
    
            } else {
                return;
            }
    
            StringBuilder sb = new StringBuilder();
    
            SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
            long _count = ConfigManager.redis_write_count;
    
            long useTime = endTime - startTime;
            long throughput = ((_count * 1000) /useTime);
            int strLength = ConfigManager.test_string_value.getBytes().length;
    
            sb.append("
    ======================================================
    "
    ); sb.append("--------- -------------- ------------- ----- ( )----- -------- -------- -------
    "
    ); sb.append("-"); sb.append(format.format(new Date(startTime))); sb.append("---"); sb.append(format.format(new Date(endTime))); sb.append("------"); sb.append(_count); sb.append("------"); sb.append(useTime); sb.append("------"); sb.append(throughput); sb.append("-----------"); sb.append(threadNumber); sb.append("-----------"); sb.append(throughput / threadNumber ); sb.append("--------"); sb.append(strLength); sb.append("byte-----"); logger.error(sb.toString()); logger.error("
    "
    ); semaphore.release(); } class RedisWriteTask implements Runnable { private Jedis jedis = null; RedisWriteTask (Jedis jedis) { this.jedis = jedis; } @Override public void run() { semaphore.tryAcquire(); while (runState) { try { long number = writeCount.decrementAndGet(); if (number < 0) { runState = false; log(); break; } String writeKey = ConfigManager.test_string_key + number; jedis.set(writeKey, ConfigManager.test_string_value); } catch (Throwable t) { logger.error("",t); // if (!jedis.isConnected()) { // jedis.close(); // jedis = JedisManager.instance().getJedis(); } } } // jedis pool jedis.close(); } } }

    ダウンロードの詳細:
    http://download.csdn.net/detail/jia281460530/9710776