Hash 在Redis中以O(1)的时间复杂度获取最后20个哈希项?
按照Redis的建议,我必须尽可能使用哈希: 小散列是在一个非常小的空间中编码的,所以您应该试试 每次可能的时候都使用哈希来表示数据。对于 实例,如果在web应用程序中有表示用户的对象, 而不是对姓名、姓氏、电子邮件、密码使用不同的键, 对所有必填字段使用单个哈希 我将拥有数百万个项目,我正在尝试将帖子存储为散列:Hash 在Redis中以O(1)的时间复杂度获取最后20个哈希项?,hash,redis,Hash,Redis,按照Redis的建议,我必须尽可能使用哈希: 小散列是在一个非常小的空间中编码的,所以您应该试试 每次可能的时候都使用哈希来表示数据。对于 实例,如果在web应用程序中有表示用户的对象, 而不是对姓名、姓氏、电子邮件、密码使用不同的键, 对所有必填字段使用单个哈希 我将拥有数百万个项目,我正在尝试将帖子存储为散列: hmset post:1 title "hello" hmset post:2 title "hi" hmset post:3 title "g'day" 现在,我知道我可以像
hmset post:1 title "hello"
hmset post:2 title "hi"
hmset post:3 title "g'day"
现在,我知道我可以像创建哈希一样轻松地检索它:
hgetall post:1
问题是我想检索多个,可能是一行20个
我尝试了以下命令,但无效(当然没有3点):
给出以下错误:
(error) ERR wrong number of arguments for 'hgetall' command
我可以在客户端执行以下操作:
hgetall post:1
然后
等等。。但这将是对网络资源的巨大浪费,也是一个潜在的性能瓶颈,因为系统平均应能同时处理至少5000个用户/秒
如果我做的失败了,那么实现这一目标的最佳方式是什么?是否有一种方法可以一次性发送此命令,而不是按顺序发送?是否有可以在哈希上进行的lrange类型操作?您的方向是正确的-对20篇文章中的每一篇文章逐个进行HGETALLs。然而,为了节省网络往返时间,请考虑使用Redis的管道,它本质上允许您对请求进行分组/批处理。或者,您可以通过实现自己的HGETALL版本来实现类似的结果,该版本通过服务器端Lua脚本接受多个键名。正如您所指出的,您可以使用管道化的请求一次发送多个命令 发件人: 可以实现请求/响应服务器,以便能够 即使客户端尚未读取旧请求,也要处理新请求 响应。通过这种方式,可以将多个命令发送到 服务器根本不等待回复,最后读取 一步回复 这被称为流水线,是一种广泛使用的技术 几十年。例如,许多POP3协议已经实现 支持此功能,大大加快了 从服务器下载新电子邮件 如果我没有记错的话,这与HMSET命令使用的技术相同,它“管道化”了多个HSET命令 Redis站点的一个片段显示了一个使用Ruby进行管道连接和不进行管道连接的示例:
require 'rubygems'
require 'redis'
def bench(descr)
start = Time.now
yield
puts "#{descr} #{Time.now-start} seconds"
end
def without_pipelining
r = Redis.new
10000.times {
r.ping
}
end
def with_pipelining
r = Redis.new
r.pipelined {
10000.times {
r.ping
}
}
end
bench("without pipelining") {
without_pipelining
}
bench("with pipelining") {
with_pipelining
}
Go还有一个名为Redigo的客户端,能够执行命令管道:
// Initialize Redis (Redigo) client on port 6379
// and default address 127.0.0.1/localhost
client, err := redis.Dial("tcp", ":6379")
if err != nil {
panic(err)
}
defer client.Close()
// Initialize Pipeline
client.Send("MULTI")
// Send writes the command to the connection's output buffer
client.Send("HGETALL", "post:1") // Where "post:1" contains " title 'hello' content 'hi' "
client.Send("HGETALL", "post:2") // Where "post:1" contains " title 'g'day' content 'g'mornin' "
// Execute the Pipeline
pipe_prox, err := client.Do("EXEC")
if err != nil {
panic(err)
}
log.Println(pipe_prox)
这很好,只要您能够轻松地显示非字符串结果。。我仍在试图找到一种将结果转换为字符串的方法,现在我得到了以下结果:
[[[116 105 116 108 101] [104 105]] [[116 105 116 108 101] [104 101 108 108 111]]]
执行以下操作也无济于事:
result, _ := redis.Strings(pipe_prox, err)
log.Println(pipe_prox)
因为这是我得到的:
[]
我将在解决此问题后尽快更新此答案。Lua或管道应该会有所帮助。此外,这可能表明您需要一个真正的数据库。
result, _ := redis.Strings(pipe_prox, err)
log.Println(pipe_prox)
[]