【发布时间】:2011-12-31 18:40:11
【问题描述】:
我需要将 IP 地址存储在 redis 哈希中。
如果将 IP 存储为整数而不是字符串,是否会节省大量内存?
我将使用 Ruby 的 IPAddr 将 IP 转换为 int。
【问题讨论】:
标签: ruby string caching integer redis
我需要将 IP 地址存储在 redis 哈希中。
如果将 IP 存储为整数而不是字符串,是否会节省大量内存?
我将使用 Ruby 的 IPAddr 将 IP 转换为 int。
【问题讨论】:
标签: ruby string caching integer redis
这取决于你如何做到这一点。在 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.hton 和 IPAddr.ntop 的作用是:
packed_ip = ip.split('.').map(&:to_i).pack('C4') # hton
ip = packed_ip.unpack('C4').join('.') # ntop
然后是关于 IPv6 之类的全部内容,但我认为 IPAddr 你已经涵盖了那里。
【讨论】:
您可能还希望重新考虑您的方法,如果您希望将应用程序转换为使用 IPv6(甚至只是支持它),那么随着 IPv6 将整数存储为整数的出现将是一个非常糟糕的主意。
现在内存/磁盘空间很便宜,因此如果可以的话,您最好投资于一个可行的面向未来的解决方案,而不是担心磁盘空间。
在这种情况下,字符串仍然是最佳选择,因为您可以在同一字段中使用 IPv6 和 IPv4。
【讨论】:
VARBINARY 这样的东西,Redis 不是 MySQL。如果你节省 4 个字节,它会节省 4 个字节,如果你扔两个 gigs,它会节省两个 gigs。此外,这不是磁盘便宜与否的问题——Redis 是一个内存数据库。阅读文档redis.io
VARBINARY 来处理所有事情。
如果将 ip 存储为整数,它将使用 4 个字节。作为字符串“abc.def.ghi.jkl”,当存储为以 null 结尾的 ascii 字符串时,它将使用 16 个字节,因此如果存储为 unicode 字符串,它至少是 4 甚至 7+ 的因数。此外,搜索整数比搜索字符串要快得多,因为您的处理器已针对比较整数进行了优化...
【讨论】:
IPAddr.new(ip).to_i 发送到 Redis 并不意味着您只存储 4 个字节,为此您需要更进一步(请参阅我的回答)。