【问题标题】:Erlang: How can I use binary keys / data with eredis?Erlang:如何在 eredis 中使用二进制键/数据?
【发布时间】:2015-08-31 13:30:59
【问题描述】:

我对 erlang 有点陌生,这是一次冒险。我想实现一个速率限制器,并在密钥生成方面遇到了一些问题。不久前,我曾尝试过实施限制器……可能是一年。我想把它清理一下......

(这是一个更大项目中的一小部分。现在我认真对待它)

我只是想我的应用程序是成功的,我每秒收到数万个请求。当我第一次编写代码时,这里是一个 sn-p:

getClientIP(Socket) ->
    {ok, {ClientIP, _ }} = inet:peername(Socket),
    TplC = tuple_to_list(ClientIP),
    {iolist_to_binary(TplC), lists:flatten(io_lib:format("~p",[TplC]))}.

makeRedisRLKeys(ClientIPStr,TimeShort,TimeLong) ->
    RKeyPrefix =  ClientIPStr ++ ":",
    {ClientIPStr, RKeyPrefix ++ integer_to_list(TimeShort) ++ ":16s", RKeyPrefix ++ integer_to_list(TimeLong) ++ ":36h"}.

所有这些代码......一遍又一遍地运行。我很好奇redis是否可以存储二进制数据。我做了一些搜索,答案是(假设是)是的......以编程方式,作为键和值。所以我在shell中尝试了:

eredis:q(R,["set",R,R]).

R 被扩展为一个 27 字节的二进制文件,但它失败了。然后我将杂项字节分配给两个变量并插入它们......结果相同。

我刚刚开始在 erlang 端重写我的限制器:

rate_limit(PartialKey) ->
    { M, S, _ } = now(),
    Time = M*1000000 + S,
    TimeLong = Time band 16#fffffffffffff000,

我知道下面的内容在语法上不正确,但我正在尝试执行以下操作:

BucketShort = <<ClientIP, Time>>,
BucketLong = <<ClientIP, TimeLong>>,

可能吗?

【问题讨论】:

  • 它是如何失败的?你得到任何有用的错误信息吗?例如eredis:q(R,["set",R,R]). 对我有用,假设 R 是一个有效的 redis 连接。
  • 可能是我使用的 erlang 版本。你在用什么?我按照 Pascal 的回答得到了和以前一样的结果:异常退出
  • 我正在使用 Erlang R17 和 Eredis 1.0.8。
  • 谢谢...想通了。我花了很长时间才回复,因为我不断收到错误。没有做 {ok,R} = eredis:start_link() 只是 R=... 和其他类似的错误。

标签: redis erlang


【解决方案1】:

eredis 查询的语法很奇怪:eredis:q(R,["set",R,R])。除非 R 是您的 eredis 应用程序的 pid,否则将失败。

“set”命令的语法是eredis:q(Pid,["set",Key,Value]).,其中 Pid 是 eredis 应用程序的 pid:{ok, Pid} = eredis:start_link(),Key 和 Value 是您要存储的键/值,表示为 io_list(list 的嵌套列表和二进制文件)。

我不明白您要准确存储什么,假设您要为每个 ClientIP 存储 2 条记录,一条带有 Time,一条带有 TimeLong。您可以使用代码实现此目的:

{ok, Pid} = eredis:start_link(),
eredis:q(Pid,["set",term_to_binary([ClientIP,short]),term_to_binary(Time)]),
eredis:q(Pid,["set",term_to_binary([ClientIP,long]),term_to_binary(TimeLong)]),

或者如果你想要 1 条记录:

eredis:q(Pid,["set",term_to_binary(ClientIP),term_to_binary([Time,TimeLong])]),

【讨论】:

  • 谢谢。该 BIF 对清理我的代码非常有帮助。 :D R 是redis PID。那条线只是一个快速测试。我喜欢使用原子与计算时间。 :) 但它仍然无法正常工作。异常退出。我会更新我的帖子。
  • 不需要。我的错。奇迹般有效。谢谢。
猜你喜欢
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 2010-09-30
  • 1970-01-01
  • 2018-02-22
  • 2015-06-01
  • 2012-06-25
相关资源
最近更新 更多