您的位置:首页 > 数据库 > Redis

Redis内存调优一例

2016-02-03 10:51 357 查看
Redis是一个在互联网圈耳熟能详的内存数据库了,使用简单,并且查询效率非常的高。我们也在很多地方使用到Redis来应对低延时的需求,比如对移动互联网广告的DMP来说,查询的时延要求4ms,对于这个时延的要求,最简单的就是用Redis来存储数据支持查询了。不过在实际使用过程中,我们却遇到了一定的困难,最主要的困难就是内存的使用。

移动互联网广告用来查询设备的ID有IMEI, AndroidID, IDFA等等主要的ID,我们的设备总量在20亿这个规模,考虑到一个安卓设备有IMEI和AndroidID两个ID,真正做为ID就是30多亿。这30多亿作为Key, Value是每个设备的标签列表。将这30多亿的设备和标签列表存储在Redis当中,如何有效的存储则成了关键的问题。

最初设想的是减少key和value的大小,我们将key做hash成long型,将标签用bit表达,压缩到1个字节。这样,每个key是2个字节,每个设备的标签是1个字节,每条记录是三个字节。

第一种尝试,将key和value都转成byte数组进行存储,然并卵,存储效率还不如将key和value当作String来存储。

第二种尝试,将key和value用String来存储,结果每条记录占用大约100个字节,对于我们这30多亿设备来讲,需要300G内存才能满足要求,按照目前的硬件要求,真是支持不了啊。

如何优化内存的使用才能让更小的内存来装载这些设备呢,Google之后发现有建议用HSET来进行存储,据说能够降低到用普通key/value的10%,查看Redis官方文档,可以发现:

Since Redis 2.2 many data types are optimized to use less space up to a certain size. Hashes, Lists, Sets composed of just integers, and Sorted Sets, when smaller than a given number of elements, and up to a maximum element size, are encoded in a very memory
efficient way that uses up to 10 times less memory (with 5 time less memory used being the average saving).

This is completely transparent from the point of view of the user and API. Since this is a CPU / memory trade off it is possible to tune the maximum number of elements and maximum element size for special encoded types using the following redis.conf directives.
hash-max-zipmap-entries 512 (hash-max-ziplist-entries for Redis >= 2.6)
hash-max-zipmap-value 64  (hash-max-ziplist-value for Redis >= 2.6)


那就尝试一下HSET吧,将key按照每500个一组进行分组,每一组存储在一个HSET中,原来执行:

SET key value

变为:

HSET keygroup key value

效果令人吃惊,平均每条记录占用的内存降低到了15个字节左右,30多亿条记录不到50G内存就可以装载了。

这几年从事大数据相关的工作,各种在小数据时期不存的问题在数据到了一定规模就的显现出来,产品的挑战、算法的挑战、技术的挑战,所有的挑战最终都是细节的了解和掌握。做大数据,问题的解决都是靠细节。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: