読者です 読者をやめる 読者になる 読者になる

RedisにBashを使って大量データを高速挿入(INSERT)する

Redisに数千万件の大量データを挿入したいという要件がありました。 手元のテキストファイルをBash使って手軽に高速に挿入したいのですがredis-cliを普通に使うとスピードが出ない。

Redisのプロトコルで流し込む方法が推奨のようです。

大量データのインサート — Redis Documentation (Japanese Translation)

しかし、自分の環境でやる限りはソケットで直接流し込む方法が最速でした。

Redisのプロトコルをソケットで流し込むのも試しましたが結局以下のような直接 SET key value の文字列をechoで流し込む方が早いのでこちらを使っています。

#!/bin/bash

# 変数は適当に変更してください
redis_host=127.0.0.1
redis_port=6379
redis_db=2
result_file=./result.txt
data_file=./key_values.txt


echo "" > $result_file
exec 6<>/dev/tcp/${redis_host}/${redis_port}
cat <&6 >> $result_file &
echo "select ${redis_db}" >&6
timer=$SECONDS
i=0
total_record=$(cat ${data_file} | wc -l)
cat ${data_file} | while read key value;
do
  i=$((++i))
  echo -e " SET \"${key}\" \"${value}\"" >&6
  #進捗状況表示
  if [ $(($i%10000)) -eq 0 ];then echo -en "Progress: $((${i}*100/${total_record}))%\r";fi
done

#結果表示
total_sec=$(($SECONDS - ${timer}))
total_ok=$(grep "+OK" ${result_file} | wc -l)
echo "${total_record} items in the ${data_file}"
echo "${total_ok} items inserted in ${total_sec} sec"

exec 6<&-

参考

bash(1): GNU Bourne-Again SHell - Linux man page