2013-05-16 6 views
3

У меня очень странная проблема: я получаю действительно дерьмовые скорости записи при использовании redis (в идеальном мире скорость записи должна приближаться к скорости записи в ОЗУ).Redis hash очень медленная скорость записи

Вот мой тест:

package redisbenchmark; 
import redis.clients.jedis.Jedis; 

public class RedisBenchmark { 

    private static final String REDIS_KEY = "anon_id"; 

    private Jedis conn; 

    private long writeTimeNano=0; 

    private RandomString stringGenerator; 

    private String[] fields; 

    public RedisBenchmark(){ 
     conn = new Jedis("localhost"); 
     stringGenerator = new RandomString(32); 
    } 

    public void run(int nbWrites, int nbReads){  
     writeBenchmark(nbWrites); 
    } 

    public void writeBenchmark(int amount){ 
     fields = new String[amount]; 

     for(int i=0; i< amount; i++){ 
      fields[i] = stringGenerator.nextString();   
     } 

     long start = System.nanoTime(); 
     for(int i=0; i< amount; i++){ 
      write(fields[i]); 
     } 
     writeTimeNano+=System.nanoTime()-start; 

     double seconds = (double)writeTimeNano/1000000000.0; 
     System.out.println("[write]nb:"+amount+"|time:"+seconds+"|speed:"+((amount*33)/(seconds*1024*1024))+" MB/s"); 
    } 

    public void write(String anonId){  
     conn.hsetnx(REDIS_KEY, anonId, "1"); 
    } 


    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     RedisBenchmark benchmark = new RedisBenchmark(); 
     benchmark.run(100000, 200); 
    } 
} 

RandomString это класс, который генерирует случайную струна (аргумент длина строки)

А ниже несколько результатов:

[написать] nb: 100000 | время: 4.408319378 | скорость: 0.713905907055318 МБ/с [написать] nb: 100000 | время: 4.447246995 | скорость: 0.707656949946542 МБ/с

Я попытался изменить параметры сохранения в hdd в файле конфигурации, но без каких-либо улучшений.

У меня есть 2 идеи:
1. Его проблема сокета, так как клиента и сервера (Redis) находятся на одной и той же машине
2. Реализация разъем имеет проблемы с производительностью

UPDATE Тестовые результаты для набор операций:

====== ====== SET
10000 запросов завершена в 0,09 секунды
50 параллельных Cli Энты
3 байта полезной нагрузки
поддерживать: 1

99,51% < = 1 миллисекунды
100,00% < = 1 миллисекунды
111111,11 запросов в секунду спецификации

системы:
- Ubuntu 11.04
- ОЗУ 8 ГБ
- Процессор Intel i5

Любое предложение будет принята с благодарностью.

+0

Какую скорость вы можете получить для операций хэширования, если вы запустите redis-benchmark? – Adam

+0

@ Адам хороший вопрос, так как я забыл добавить результаты тестов, но я добавлю их сейчас и из того, что могу сказать, очень хорошие результаты – Stephan

ответ

4

Вам нужно немного подумать о том, что вы действительно тестируете с помощью этой программы. Я могу сказать вам, что это не Редис, а скорее способность вашей системы запускать игру для пинг-понга между двумя процессами (потому что все ваши вызовы hsetnx синхронны).

Пожалуйста, прочтите this page, прежде чем пытаться сравнить Redis, это определенно поможет вам.

Ваше предположение о том, что скорость Redis должна приближаться к скорости записи ОЗУ, несколько наивна. Redis является удаленным магазином, а для операций O (1) большая часть накладных расходов связана с расходами на связь. Для синхронного трафика (например, вашего примера) это также связано с затратами на планировщик ОС.

Если вы хотите последовательно применять множество команд, вам необходимо использовать pipelining.Или, если вы не заботитесь о последовательности, вы можете работать одновременно с несколькими соединениями (это режим по умолчанию для redis-benchmark). Или вы можете попробовать отправить асинхронные команды. Во всех случаях идея состоит в том, чтобы амортизировать стоимость обращений к серверу Redis

С конвейерной обработкой на нескольких соединениях с асинхронным трафиком вы получите максимальную пропускную способность, которую Redis может достичь на этой машине.

+0

+1 для полезной информации. Что касается скорости ОЗУ, я только сказал, что, поскольку он работал на одном и том же компьютере, таким образом, не может возникнуть узкое место в сети. Я знаю об использовании нескольких клиентов или конвейерной обработке, но я решил не использовать его, поскольку я хотел моделировать худший сценарий: один поток, который выполняет последовательные вызовы и считывает результат после каждого вызова. Тем не менее, я бы ожидал гораздо большую скорость, чем полученную. – Stephan

+0

Ни одна сеть не означает никаких затрат на связь. IPC также имеют стоимость. Вы можете попробовать redis-benchmark с -c 1, чтобы ограничить параллелизм одному соединению и сравнить яблоки с яблоками. –

+0

ур прав о них яблоки: D я побежал './redis-benchmark -c 1 -d 33 -n 100000 -t SET', и он выполнен в 4.32 сек, как я получил. Но все же я ожидал большего ... может быть, у меня нет полной четкой картины о том, почему в этом случае медленная – Stephan

Смежные вопросы