首页 > 解决方案 > 在生菜中,我发现 redis 集群上的 async mget 比流水线慢得多

问题描述

我正在为一个新项目编写一些基准测试,但遇到了一个问题,即生菜(版本 5.1.3),我发现下面的代码使用了 mget:

 @Override
public Set<V> getKeys(final Set<Long> keySet) {

    try {
        return asyncCommands.mget(keySet.toArray(new Long[0])).get(
                5, TimeUnit.SECONDS
        ).stream().map(keyValue -> keyValue.getValue()).collect(Collectors.toSet());
    }  catch (Exception e) {
        throw new RuntimeException(e);
    }

比自己使用流水线要慢得多(比如慢 100 倍以上):

List<RedisFuture<V>> futures = new ArrayList<>(keySet.size());
    keySet.forEach(
            key -> futures.add(asyncCommands.get(key))
    );

    asyncCommands.flushCommands();

    LettuceFutures.awaitAll(5, TimeUnit.SECONDS,
        futures.toArray(new RedisFuture[0]));

    final Set<V> collect = futures.stream().map(
            future -> {
                try {
                    return future.get(1, TimeUnit.SECONDS);
                } catch (Exception e) {
                    log.warn("", e);
                    throw new RuntimeException();
                }
            }
    ).filter(
            Objects::nonNull
    ).collect(Collectors.toSet());
    return collect;

与 redis 服务器报告的相比,这两个似乎都相当慢,但可能还有其他因素。javadocs说mget应该使用流水线,那么为什么它比我自己做流水线要慢得多?我做错了什么?

编辑:对于我启用了 autoflushcommands 的 mget,对于流水线它被禁用。

更新:发现性能低下的罪魁祸首是编解码器慢,当编解码器速度慢时,有什么办法可以提高整体吞吐量?

标签: javaperformanceredislettuce

解决方案


推荐阅读