地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Redis】redis-py pipelineを使う

ある関数内で複数回Redisとのやり取りをしている場合はpipelineを用いることで処理を一括でRedisに投げることができる機能。何が嬉しいかというとプロセス間通信によるRTTを減らすことができる。

以下はサンプル。many_get()とmpipe_line()が計測対象。データ量は10000で固定。

def stop_watch(func) :
    @wraps(func)
    def wrapper(*args, **kargs) :
        start = time.time()
        result = func(*args,**kargs)
        process_time =  time.time() - start
        print(f"{func.__name__:<15}: {str(process_time)[:5]}[s]")
        return result
    return wrapper


@stop_watch
def many_set():
    for i in range(10000):
        r.set(i, i)

@stop_watch
def many_get():
    for i in range(10000):
        r.get(i)

@stop_watch
def mpipe_line():
    with r.pipeline() as pipe:
        for key in range(10000):
            pipe.get(key)
        pipe.execute()

実行結果はこちら。予想以上の結果が帰ってきた。

root@client001:/# python /usr/local/tools/test/multi.py
many_set       : 1.770[s]
many_get       : 1.740[s]
mpipe_line     : 0.097[s]

github.com

おまけ

ttlが設定されていないキー一覧を取得するluaスクリプト

local t = {} 
local i = 1 
for _,v in ipairs(redis.call('KEYS', '*')) 
do 
  if redis.call('TTL',v) == -1 then
    t[i] = v 
    i = i + 1
  end
end 
return t