redisプロトコルをbashで出力する話


大量のデータをredisに流し込む際に、コマンドを送るよりバルクでプロトコル流すと速いので、
http://redis-documentasion-japanese.readthedocs.io/ja/latest/topics/mass-insert.html

pythonで書いてみたけど

redis_bulk.py
def cmd2bulk(*cmd):
    z = lambda x: (len(bytes(str(x), "utf-8")), x)
    return "*%d\r\n%s" % (len(cmd), "".join(["$%d\r\n%s\r\n" % z(x) for x in cmd]))

if __name__ == '__main__':
    import sys
    import unittest

    class TestRedisBulk(unittest.TestCase):

        def test_redis_proto1(self):
            expect = "*3\r\n$3\r\nSET\r\n$6\r\nKEY985\r\n$8\r\nVALUE985\r\n"
            result = cmd2bulk("SET", "KEY985", "VALUE985")
            self.assertEqual(expect, result)

        def test_redis_proto2(self):
            expect = "*5\r\n$4\r\nSADD\r\n$4\r\nhoge\r\n$9\r\nあああ\r\n$6\r\nいい\r\n$3\r\n\r\n"
            result = cmd2bulk("SADD", "hoge", "あああ", "いい", "う")
            self.assertEqual(expect, result)

    unittest.main()

bashでもいけるんじゃね

redis_bulk_test.sh
function redis_bulk() {
    printf "*%d\r\n" "${#@}"
    for x in "${@}"; do
        printf "$%d\r\n%s\r\n" $(echo -ne "$x" | wc -c) "$x"
    done
}

redis_bulk HMSET "ほげ" foo 123 bar "ばー" | redis-cli --pipe

っていう話。

注意

bashの方は実運用してないから未知数。

pythonの方は100万件くらいの塊を連続で一気に流し込んでも問題なく動いてます。
コマンドを都度送るより断然速いです。