【问题标题】:Redis: should I convert IPs into integers?Redis:我应该将 IP 转换为整数吗?
【发布时间】:2011-12-31 18:40:11
【问题描述】:

我需要将 IP 地址存储在 redis 哈希中。

如果将 IP 存储为整数而不是字符串,是否会节省大量内存?

我将使用 Ruby 的 IPAddr 将 IP 转换为 int。

【问题讨论】:

    标签: ruby string caching integer redis


    【解决方案1】:

    这取决于你如何做到这一点。在 Redis 中,键和(叶)值是字符串。如果您将 IP 地址转换为 int 并将其发送到 Redis,就像以下代码一样,您不会节省太多:

    redis.hset("xyz", "ip", IPAddr.new(ip).to_i)
    

    例如IP“255.255.255.255”是15个字节的点四边形,它的整数表示“4294967295”保存为字符串时是10个字节,这就是上面的代码所做的。

    要减少存储在 Redis 中的四个字节,您必须发送原始字节“\xFF\xFF\xFF\xFF”。

    在 Ruby 中你会这样做:

    packed_ip = IPAddr.new(ip).hton
    redis.hset("xyz", "ip", packed_ip)
    

    然后当你读回来时

    packed_ip = redis.hget("xyz", "ip")
    ip = IPAddr.ntop(packed_ip)
    

    IPAddr.htonIPAddr.ntop 的作用是:

    packed_ip = ip.split('.').map(&:to_i).pack('C4') # hton
    ip = packed_ip.unpack('C4').join('.') # ntop
    

    然后是关于 IPv6 之类的全部内容,但我认为 IPAddr 你已经涵盖了那里。

    【讨论】:

    • 感谢 Theo 的详尽回答。
    【解决方案2】:

    您可能还希望重新考虑您的方法,如果您希望将应用程序转换为使用 IPv6(甚至只是支持它),那么随着 IPv6 将整数存储为整数的出现将是一个非常糟糕的主意。

    现在内存/磁盘空间很便宜,因此如果可以的话,您最好投资于一个可行的面向未来的解决方案,而不是担心磁盘空间。

    在这种情况下,字符串仍然是最佳选择,因为您可以在同一字段中使用 IPv6 和 IPv4。

    【讨论】:

    • 这里没有VARBINARY 这样的东西,Redis 不是 MySQL。如果你节省 4 个字节,它会节省 4 个字节,如果你扔两个 gigs,它会节省两个 gigs。此外,这不是磁盘便宜与否的问题——Redis 是一个内存数据库。阅读文档redis.io
    • 道歉 :) 我已经删除了数据库引用,但这一点仍然存在。如果您想利用(和未来证明)使用 redis 的应用程序,那么 IPv6 是需要考虑的事情,在这种情况下,字符串将是最佳选择,因为 IPv6 不能存储在 int 中(它可以存储在 2* big int 中)。使用双冒号表示法,您可以进一步缩小它。
    • 你说得对,IPv6 的权衡不太清楚。总是使用 16 字节,或者希望大多数值在表示为字符串时小于 16 字节?但是,在 Redis 中存储 16 字节整数是没有问题的,只需将它们以相同的方式打包就可以了。 Redis 不在乎,在某种程度上你可以认为它使用VARBINARY 来处理所有事情。
    【解决方案3】:

    如果将 ip 存储为整数,它将使用 4 个字节。作为字符串“abc.def.ghi.jkl”,当存储为以 null 结尾的 ascii 字符串时,它将使用 16 个字节,因此如果存储为 unicode 字符串,它至少是 4 甚至 7+ 的因数。此外,搜索整数比搜索字符串要快得多,因为您的处理器已针对比较整数进行了优化...

    【讨论】:

    • 最后一句不相关。如果 IP 是值,则不会搜索,如果它们是键,则也不会搜索,因为它都是哈希查找。此外,仅将IPAddr.new(ip).to_i 发送到 Redis 并不意味着您只存储 4 个字节,为此您需要更进一步(请参阅我的回答)。
    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 2015-07-28
    • 2019-11-09
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    相关资源
    最近更新 更多