妈妈再也不用担心我的程序 OOM 啦 - 一个基于 Redis 的分布式内存

2015-11-11 00:01:51 +08:00
 wangleineo
Dmem ( Distributed memory )是用 python 实现的一个分布式内存的解决方案,把 Python 的基础数据类型映射到 Redis 上,通过一个“透明”的 Redis Client 实现在多个节点上存取数据。

**Github**:[https://github.com/RealHacker/dmem]( https://github.com/RealHacker/dmem)

应用场景:

- 程序对于内存需求较大,单节点无法满足时,无需更改代码逻辑即可支持分布式内存。
- 需要分布式存储多层数据结构,比如一个 list ,其中每个元素是一个 dict 。( Redis 命令只支持单层数据结构)
- 代码洁癖患者,可以使用 Python 原生操作符(`x[y], del x.y, x in y`)和方法来处理分布式对象。

废话不多说,看代码:

from dmem import *
# Configure your redis instances pool
RedisClientPool.get_pool().load_config({
"redis1": {"host":"192.168.1.1", "port": 6379, "db":0},
"redis2": {"host":"192.168.1.2", "port": 6379, "db":0},
"redis3": {"host":"192.168.1.3", "port": 6379, "db":0},
})
# Create a list
mylist = RedisList([1, "abc", 3.1415])
# Now the list is alive on Redis
print mylist[1] # actually retrieved with LGET command
# output: 'abc'
print mylist[0:2] # map to LRANGE command
# output: [1, 'abc']
del mylist[0] # map to LREM command
print mylist[:]
# output: ["abc", 3.1415]
s = RedisStr("Redis string")
# Now the string lives in Redis
mylist.append(s) # APPEND command
print len(mylist) # STRLEN command
# output: 3
print mylist[-1].getvalue() # GET command
# output: 'Redis string'
mydict = RedisDict({"a":1234}) # HSET commands
# Now the dict lives in Redis as a hashmap
mydict["list"] = mylist # HGET command
print mydict.keys() # HKEYS command
# output: ['a', 'list']
for k,v in mydict.items(): # HGETALL command
print k, v
# output: a 1234
# output: list <redislist.RedisList object at 0x01CDEF30>
print mydict["list"][0]
# output: 'abc'
obj = RedisObject()
# For redis object, the attributes are stored in Redis
obj.attr1 = "abc"
obj.attr2 = mydict
print obj.attr2['list'][0]
# output: 'abc'

欢迎提建议、报 Bug 。
4128 次点击
所在节点    分享创造
24 条回复
ryd994
2015-11-11 00:22:48 +08:00
这样的性能会不会不如 swap ?
另外用 mmap 是好东西
wangleineo
2015-11-11 00:29:16 +08:00
@ryd994 没有测试过, 不过网络性能一般会比磁盘 I/O 高一些,否则 memcached/redis 集群都没意义了。
ryd994
2015-11-11 00:35:25 +08:00
@wangleineo 那可不一定。磁盘是带缓存的。而且热数据都在内存里。
binux
2015-11-11 00:38:28 +08:00
延迟
raingolee
2015-11-11 00:38:41 +08:00
程序对于内存需求较大,单节点无法满足时,无需更改代码逻辑即可支持分布式内存
---

对比 sentinel 有什么区别呢?
楼主其实我还是不太明白 Dmem 的用处?
wangleineo
2015-11-11 00:49:30 +08:00
@raingolee 比如存取一个列表元素, RedisList 和原生的 list 一样: list[1],而不是 redis.client.lindex(...)。如果数据是存在内存中的 list 中,要迁移到 redis ,不用改变代码逻辑,只要把 list 换成 RedisList 就好了。
kendetrics
2015-11-11 00:58:33 +08:00
我感觉会比 swap 更卡。。
ryd994
2015-11-11 01:06:47 +08:00
其实可以用 tmpfs 开 nfs ,然后 swapfile 放到 nfs 上。估计性能还比你这样好。不过万一断网就会崩
mzer0
2015-11-11 02:13:11 +08:00
没啥用, 我的服务器目前还没出现过内存不够用的情况.

另外你这东西弄得太复杂了, 纯 C 语言实现的或许还会有人试试.
msg7086
2015-11-11 04:56:19 +08:00
@ryd994 可是这个场景里内存都吃光了啊……哪有地方给你 caching ……
ryd994
2015-11-11 05:27:55 +08:00
@msg7086 他这样把所有变量都直接改到 memcache 里去,内存根本没用到多少
如果我对代码的理解没错的话,缓存是以整个 list 或者 dict 为单位的
另外我很好奇这个 self.cache 在什么情况下会被回收

说实话,我真心觉得 nfs 上挂 swap 虽然作死,但效果应该不差。
wangleineo
2015-11-11 09:38:23 +08:00
@mzer0 为什么用 c 语言就不复杂呢?

@ryd994 self.cache 是用在 loaded 这个 context 中,退出 cache 就释放

为啥都纠结性能问题呢?这和直接用 redis 的命令性能没什么不同
ryd994
2015-11-11 09:52:08 +08:00
@wangleineo 纠结性能是因为你的定位是“分布式内存”,是要解决 OOM ,那性能就是要和物理内存比的。
如果你的定位是“易用的 memcached 客户端”的话,我觉得写的很好。
canesten
2015-11-11 10:02:31 +08:00
就是 Python 版的 Redisson ?
wangleineo
2015-11-11 10:42:03 +08:00
@ryd994 的确有点标题党了,其实我的定位是:如果你能接受 Redis 的性能,就可以考虑用这个。


@canesten 概念上类似,不过 Redisson 有很多功能,比如异步,我都没有实现。
dreampuf
2015-11-11 10:58:45 +08:00
楼上纠结 RAM+Network 不如 Disk 的诸位


类库封装了 redis 支持多个节点,但是实现比较简单,没有考虑拆分的情况,集群容量还是受最小单节点限制
https://github.com/RealHacker/dmem/blob/master/dbase.py#L19
wangleineo
2015-11-11 11:16:55 +08:00
此图甚好 另外有一个 post http://norvig.com/21-days.html#answers
mzer0
2015-11-13 00:29:12 +08:00
@wangleineo C 语言实现一个分布式的内存,应该只需要几百行代码;而我认为,先不谈分布式内存的存在意义, redis+python 是不能接受的,硬要说的话,理由是“没有理由”——就是我不想这样做,我宁愿自己编一个。或许某个俄国人实现过,要知道,俄国人最喜欢这些东西了,但我敢肯定没人用。
GeekGao
2015-11-13 02:04:09 +08:00
感觉没啥适用场景。实际上我用 zookeeper+zmq 实现单机内存统计和消息通信,内存不够或者机器下线,直接把任务交给其他相对大点的内存机器去跑了
wangleineo
2015-11-13 10:58:17 +08:00
@mzer0 好吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/235223

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX