当前位置: 首页 > 知识库问答 >
问题:

将数据从redis哈希转储到postgresql表的更快方法

盛建德
2023-03-14

我正在进行批量数据处理,为了速度起见,我首先将数据存储在redis中,然后每隔2分钟将其转储到postgresql数据库中。我使用了redis散列来存储数据,甚至redis中的散列键也对应于数据库表中的列。

使用redis.scan()获取存储数据行的redis哈希列表,然后使用redis.hgetall()获取哈希中的数据。从那里,我在SqlAlChemy中创建了一个SQL插入语句,并执行批量数据插入到数据库中。

我面临的问题是,我必须首先使用扫描提取包含我的数据的密钥:

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获取数据,并且能够立即将该数据用于批量SQL插入,因为redis哈希中的键对应于postgresql表中的列名
  2. 即使1是不可能的,至少必须有一个更快的方法来使用hgetall()从redis获取数据,并对整个条目(即散列中的所有条目)进行一些动态解码,而不是迭代到每个键值

编辑:

我读过postgresql的外国数据包装器,特别是redis_fdw,我想知道它是否能解决我的情况,以最快的速度将数据从Redis移动到Postgresql,并尽可能减少麻烦

共有1个答案

皮献
2023-03-14

redis\u fdw是一条路要走。请记住,哈希集的每个成员在相应的Pg外部表中不会是不同的行。相反,它将在外部表中为每个Redis散列创建一行,并为所有散列值使用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哈希集的一行myhash。此行将有一个包含redis哈希的所有键/值对的作为键myhash和作为值的postgres数组。

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)
 类似资料:
  • 问题内容: 我在Redis中存储MessagePacked哈希时遇到问题。我在下面粘贴了一个测试用例。从Redis中提取打包数据并对其进行解压缩时,哈希会略有损坏。当哈希值超出一定长度时,似乎会发生这种情况,尽管我不能肯定地说。 我正在使用Redis 2.4.17(默认配置),Ruby 1.9.3p194,MessagePack 0.4.7和Redis gem 3.0.2。使用节点也会发生相同的问

  • 所以,我有一个带有数组的哈希,就像这样: 我想将它们合并到一个哈希数组中,组合相应的元素。 结果应该是这样的: 知道如何有效地做到这一点吗? 请注意,真实世界的使用场景可能包含数量可变的散列键。

  • 问题内容: 我对Redis还是很陌生,希望看看是否有可能。想象一下我正在接收这样的数据: 并为另一个帐户接收此数据: 我想以类似的格式将这些数据保留在Redis中: 对于xyz: 所以问题是我应该使用哪种数据类型来存储此Redis? 问题答案: 如果您的目标是检查是否用作该帐户的解决方案,则解决方案应类似于: 样本数据 执行此操作( 使用redis集 ): 然后,您可以通过以下命令检查是否用作该帐

  • 问题内容: 我想在redis中存储哈希数组,最好的编码方法是什么? 问题答案: AFAIK的唯一方法是取消引用它们。假设您有2个散列数组,例如:。 您将它们分别存储,然后创建一个引用它们全部的SET: 然后,您可以通过查询set:来检索它们全部,然后调用所有返回的键来重建原始的哈希数组。 我希望这是有道理的。而且,如果您找到了更聪明的方法,我将很高兴听到。

  • Hashmaps通常使用桶的内部数组(表)来实现。在通过键访问hashmap时,我们使用键类型特定(逻辑类型特定)的hash函数获得键的hashcode。然后我们需要将hashcode映射到实际的内部桶表索引。 有时,内部表可能会收缩和扩展,这取决于hashmap填充率。那么可能是散列码- 例如,我们的哈希函数返回32位无符号整数值 时刻A:内表容量为10000 时刻B:内工作台容量为100000

  • 我想获取一个MIDI文件,读取它,然后将数据存储在某种数据结构中。通过这个网站,我找到了一种阅读该文件的简单方法,它就像一个符咒: 读取MIDI文件 现在我需要找到一种方法来获取输出并存储它。哈希映射似乎并不理想,因为键需要是唯一的,而类型对象列表似乎并不理想。我最好的选择是什么。我想我可能会把它输出到文本或csv。。。思想? 更新:关于我已经拥有的更多细节。 这是我得到的输出(通过System.