1

大量のデータ処理を行っています。速度を上げるために、最初にデータを redis に保存してから、2 分間隔で postgresql データベースにダンプします。データを格納するために redis ハッシュを使用しましたが、redis のハッシュ キーでさえ、データベース テーブルの列に対応しています。

redis.scan()データの行を格納する redis ハッシュのリストを取得するために使用し、ハッシュ内のデータを取得するために使用しredis.hgetall()ています。そこから、SqlAlchemy で SQL Insert ステートメントを作成し、データベースへの一括データ挿入を実行します。

私が直面している問題は、最初に SCAN を使用してデータを含むキーを抽出する必要があることです。

redis_match = 'data:row_keys:*'
row_keys = rdb.scan_iter(match=redis_match, count=limit_no)

そこから、各ハッシュのすべてのデータをフェッチします。

for index, row_id in enumerate(row_keys):
    row_data = rdb.hgetall(row_id)

row_data は次の形式ですkey:valueが、形式で保存されるbyteため、次を使用して各キーと値を手動でデコードするために余分なオーバーヘッドが発生します。

for key, value in row_data.items():
  key = ast.literal_eval(key.decode('unicode_escape'))
  value = ast.literal_eval(value.decode('unicode_escape'))

私はこれが多すぎると感じており、よりエレガントな方法が必要です:

  1. hgetall() を使用して redis からデータを取得し、redis ハッシュのキーが postgresql テーブルの列名に対応するため、そのデータを一括 SQL 挿入にすぐに使用できます。
  2. 1 が不可能な場合でも、少なくとも hgetall() を使用して redis からデータを取得し、エントリ全体、つまり各キーと値を反復する代わりにハッシュ内のすべてのエントリをオンザフライでデコードするためのより迅速な方法が必要です。

編集:

私はpostgresqlのForeign Data Wrappers、特にredis_fdwについて読んだことがあります.RedisからPostgresqlにデータを移動するためのより高速な方法を可能な限り最小限のトラブルで得るという私の状況を解決するものかどうか疑問に思っています.

4

1 に答える 1

1

redis_fdw行く方法です。ハッシュ セットの各メンバーは、対応する Pg 外部テーブルの異なる行にならないことに注意してください。代わりに、Redis ハッシュごとに 1 つの行を外部テーブルに作成し、すべてのハッシュ値に Pg 配列を使用します。

たとえば、Redis の次のハッシュの場合:

myhash = {a:1, b:2}

外部テーブルを作成できます:

CREATE FOREIGN TABLE my_pg_hash (key text, val text[])
SERVER redis_server
OPTIONS (database '0', tabletype 'hash', tablekeyprefix 'myhash');

外部テーブルmy_pg_hashには、Redis ハッシュ セット全体の 1 つの行が含まれmyhashます。この行には、redis ハッシュのすべてのキーと値のペアを含むpostgres 配列myhashがキーおよび値として含まれます。

SELECT * FROM my_pg_hash;

 key      |    val    
----------+-----------
 myhash   | {a,1,b,2}
(1 row)

Pg のunnest()関数を使用して、val 配列を個別の行に分割できます。

SELECT key, unnest(val) FROM my_pg_hash;

  key   | unnest 
--------+--------
 myhash | a
 myhash | 1
 myhash | b
 myhash | 2
(4 rows)
于 2016-01-06T09:56:48.190 に答える