遵循Redis的建议,我必须尽可能使用哈希:
小哈希在非常小的空间中编码,所以你应该尝试 每次可能使用哈希表示您的数据。对于 实例,如果您有在Web应用程序中表示用户的对象, 而不是使用不同的名称,姓氏,电子邮件,密码, 使用包含所有必填字段的单个哈希。
并且我将有数百万件物品,我试图将帖子存储为哈希:
hmset post:1 title "hello"
hmset post:2 title "hi"
hmset post:3 title "g'day"
现在,我知道我可以像创建它一样简单地检索哈希:
hgetall post:1
问题在于我想要检索多个,可能在一行中检索20个。
我尝试了以下没有工作的命令(当然没有3个点):
hgetall post:1 post:2 post:3 post:4...
发出以下错误:
(error) ERR wrong number of arguments for 'hgetall' command
我可以做这个客户端:
hgetall post:1
然后
hgetall post:2
依此类推..但这将是巨大的浪费网络资源和潜在的性能瓶颈,因为系统应该能够平均同时处理至少5000个用户/秒。
我做错了,完成此任务的最佳方法是什么?有没有办法发送这个命令一次而不是顺序执行?是否有可以在哈希上进行的 lrange 类型的操作?
答案 0 :(得分:1)
你正朝着正确的方向前进 - 为20个帖子中的每个帖子一个接一个地做你的HGETALL。但是,为了节省网络往返次数,请考虑使用Redis的流水线技术,它基本上允许您对请求进行分组/批处理。或者,您可以通过实现自己的HGETALL版本来实现类似的结果,该版本接受带有服务器端Lua脚本的多个密钥名称。
答案 1 :(得分:1)
正如您所指出的那样,您可以使用 Pipelined 请求一次发送多个命令。
来自the Redis page dedicated to Pipelining:
可以实现请求/响应服务器以便它能够 即使客户端尚未阅读旧请求,也会处理新请求 响应。这样就可以发送多个命令 服务器根本没有等待回复,最后阅读了 只需一步即可回复。
这称为流水线技术,是一种广泛使用的技术 几十年。例如,已经有许多POP3协议实现 支持此功能,大大加快了这一过程 从服务器下载新电子邮件。
如果我没有错,那就是 HMSET 命令使用的技术," Pipelines"多个 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)
这就是我得到的:
[]
我会在设法解决此问题后立即更新此答案。