在可伸缩系统中,我经常需要从PostgreSQL查询数据并将其缓存在Redis中。我想知道一次可以传输多少数据,何时需要考虑进行多批处理或使用消息队列。
一个用例是,当用户登录时,我要将用户朋友的所有用户ID缓存到Redis。我们是一个社交平台,因此用户可能有很多朋友,一千,一万甚至更多。
因此,当用户登录时,我需要执行以下操作(例如,使用Python,但问题应该是语言不明确的)
cur = pg_conn.cursor()
cur.execute('SELECT friend_id FROM friends WHERE user_id = ?', user_id)
friend_ids = [item['friend_id'] for item in cur.fetchall()]
cur.close()
redis.sadd('%s.friends' % user_id, *friend_ids)
我的问题是,这段代码可以处理多少数据量。假设friend_id是一个UUID(36字节),我最多可以查询多少friend_id,那么这段代码可以可靠地将这些id从PostgresSQL传输到Redis?
哪些因素会影响数据传输大小的上限?假设应用程序服务器,PostgreSQL和Redis都在AWS的同一区域中运行。
可靠地说,我的意思是上面的代码不太可能失败(> 99%或99.9%左右),但不必像银行一样可靠。
答案 0 :(得分:1)
根据redis文档: https://redis.io/commands/sadd
自1.0.0起可用。
时间复杂度:每个元素添加O(1),因此O(N)要添加N 带有多个参数的命令调用时的元素。
SADD的性能非常好,并且不会依赖于redis键的当前大小,您无法提高此性能(通过建模/更改查询...),这已经是最好的了!
这意味着仅网络(主要是Redis与服务器之间的ping时间,您可以测量)和N的大小很重要(主要是由于网络带宽的使用)。
Redis是单线程的,因此一次仅处理一个SADD,您将需要非常大的插入(要插入很多元素,我觉得10k看起来并不令人印象深刻)以减慢Redis。在大多数情况下,您更担心在Redis上内存不足(您应该进行监督)。
这些参数仅取决于您的基础架构质量,该质量应该很高(或者您可以通过更改云提供商上的服务器/ vpc轻松地改善它)。
如果您真的担心网络上有效负载的大小,可以使用lua脚本执行SADD命令并压缩有效负载,然后再调用redis并将其解压缩到脚本内部,这会减少网络负载
出于可靠性考虑,如果第一个SADD出于某种原因失败(例如,请参见断路器模式),则最好使用某种自动重试过程将其放入Redis。