【问题标题】:Redis bitmap data to Mysql - ETL strategiesRedis 位图数据到 Mysql - ETL 策略
【发布时间】:2014-05-08 12:45:00
【问题描述】:

我真的很喜欢 redis 和 mysql,并广泛使用它们。我有兴趣从我的 redis 实例中清除不再需要的某些键,因为内存很昂贵。我想把它停在磁盘上并永远留在那里。我不是很讲究如何,但我正在探索将它放在mysql中。对于大多数 redis 数据类型来说,这是小菜一碟。它要么是字符串,要么是 json 编码可以轻松处理的东西。我的问题是位图,它是数据的二进制表示。

这是我天真的 psydo 代码/python 方法:

#create an arbitrary bitmap with every third bit ticked to 1
for i in range(100):
    rediscon.setbit('thekey',i*3, 1)

#get the value as a string
thevalue = rediscon.get('thekey')#is get appropriate for a bitmap?
#this looks something like "@ \b\x02\x00\x80 "

#do the insert into mysql
mysql.query("insert into table (key, value) VALUES ('thekey', "+MySQLdb.escape_string(thevalue)+")")

#do a sanity check, restore the key back to redis
#get the value from mysql and put it back in redis with a new key
val = MySQLdb.query("select value from table where key='thekey'")
rediscon.set('thekey_new', val)

print rediscon.bitcount('thekey')#this prints correctly as 100
print rediscon.bitcount('thekey_new')#this is wrong, it prints a number much less than 100

mysql 引擎类型是 myisam,我认为这并不重要。我已经为values 的列类型尝试了 BLOB 和 LONGTEXT。我想在位图上做get 吗?如何在 mysql 中插入二进制数据?

我该怎么做?我希望能够把这个位图放到mysql中,以后有能力恢复。谢谢!

【问题讨论】:

    标签: mysql redis binary-data


    【解决方案1】:

    rediscon.get() 是字节安全的,所以是的,这将安全地为您提供位图。

    问题在于您的 SQL 语句。您可以base64 在存储二进制数据之前对其进行编码。

    您的方法看起来不错,但如果它是大量数据(如在“键”中,而不是在此处谈论“字节”),请始终使用非事务性pipelining。 python实现见here

    希望这有帮助,TW

    【讨论】:

    • 我的最终解决方案中没有使用您的答案,但我还是投了赞成票。我熟悉流水线。在执行此操作时,mysql insert(磁盘)比redis read(内存)花费的时间要长得多,所以我不在乎。或者,换一种说法,为大约 1gb 的 redis 数据执行此操作需要几分钟,我猜流水线会为我节省几分之一秒左右的时间。感谢您的意见
    • 谢谢,您对流水线的看法是正确的。如果 SQL 插入是瓶颈(并且您不能/不需要通过批量插入来改进它),那么流水线没有任何好处。性能方面和并发方面。
    【解决方案2】:

    我能够让它工作,我上面最初的尝试实际上在概念上是正确的。有一个小的逻辑错误导致我的健全性检查失败。

    我按照 Tw Bert 的建议尝试了 base64。这不是必需的,但我可能会使用它。我可以将redis.get 的结果直接放入我的 mysql insert 语句中,然后将其拉出来进行健全性检查,它工作正常。我也可以base64编码我放在mysql中的内容,然后当我从mysql中读取出来时进行base64解码。初步来看,与原始二进制文件相比,使用 base64 编码似乎使我在 mysql 中额外花费了大约 20% 的磁盘。但是,我认为我并不关心这一点,并且可能愿意为将数据以 ascii 格式保存,以便我可以更好地“看到”它而支付这笔费用。

    我现在可以将它与一些基本的密钥选择结合起来,并将我想从 redis 归档的任何密钥子集备份到磁盘。我希望这对将来的人有所帮助。

    更新: 事实证明我没有这样做。我的解决方案非常简单,不保证上述复杂性。我的键的命名结构是分片值在开头,然后是该键的详细信息。所以,我做了四件事:

    (1) 我运行KEYS id_123* 来获取我想要存档的所有密钥(密钥很少,所以KEYS 不是一个巨大的障碍,如果你有大量密钥,请使用SCAN) (2) 启动一个新的 redis-server(它可以在同一台机器上,使用不同的端口) (3)MIGRATE所有找到的新redis-server的key。 (4) 发出SAVE 以获取RDB 文件并随心所欲地处理。

    这非常简单,并且允许您将其保留为“redis”格式,因此稍后重新提取它非常简单。

    【讨论】:

    • 哈哈哈,可爱的图片 :) 很高兴听到你成功了。 base64 评论:注明。我猜错了。
    • 作为旁注,这也可能是一个有趣的阅读(如果你不害怕一点实验):Matt Palmer - Want to use Redis? Got more data than memory? Use NDS!
    • 谁否决了我的回答?你能评论一下为什么你觉得这是一个糟糕的答案吗?
    • @Landon 我知道这个答案很旧,但我很好奇您使用什么数据类型在 MySQL 中持久化位图,以及是否可以直接对持久化的位图执行按位操作使用 SQL 的版本?我正在研究 Redis 位图分析方法已普及 here,并考虑是否有可能创建一种混合方法,将实时数据存储在 redis 位图中,历史值保存在 MySQL 中,但仍然能够执行 btiwse 比较两者之间。
    • @LastAngryMan 我用我所做的更新了我的帖子。我的方向与我最初的尝试不同....
    猜你喜欢
    • 2017-01-16
    • 2014-05-29
    • 2016-12-28
    • 2015-09-04
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    相关资源
    最近更新 更多