Dmem ( Distributed memory )是用 python 实现的一个分布式内存的解决方案,把 Python 的基础数据类型映射到 Redis 上,通过一个“透明”的 Redis Client 实现在多个节点上存取数据。
Github:https://github.com/RealHacker/dmem
应用场景:
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 。
1
ryd994 2015-11-11 00:22:48 +08:00
这样的性能会不会不如 swap ?
另外用 mmap 是好东西 |
2
wangleineo OP @ryd994 没有测试过, 不过网络性能一般会比磁盘 I/O 高一些,否则 memcached/redis 集群都没意义了。
|
3
ryd994 2015-11-11 00:35:25 +08:00
@wangleineo 那可不一定。磁盘是带缓存的。而且热数据都在内存里。
|
4
binux 2015-11-11 00:38:28 +08:00
延迟
|
5
raingolee 2015-11-11 00:38:41 +08:00
程序对于内存需求较大,单节点无法满足时,无需更改代码逻辑即可支持分布式内存
--- 对比 sentinel 有什么区别呢? 楼主其实我还是不太明白 Dmem 的用处? |
6
wangleineo OP @raingolee 比如存取一个列表元素, RedisList 和原生的 list 一样: list[1],而不是 redis.client.lindex(...)。如果数据是存在内存中的 list 中,要迁移到 redis ,不用改变代码逻辑,只要把 list 换成 RedisList 就好了。
|
7
kendetrics 2015-11-11 00:58:33 +08:00
我感觉会比 swap 更卡。。
|
8
ryd994 2015-11-11 01:06:47 +08:00
其实可以用 tmpfs 开 nfs ,然后 swapfile 放到 nfs 上。估计性能还比你这样好。不过万一断网就会崩
|
9
mzer0 2015-11-11 02:13:11 +08:00
没啥用, 我的服务器目前还没出现过内存不够用的情况.
另外你这东西弄得太复杂了, 纯 C 语言实现的或许还会有人试试. |
11
ryd994 2015-11-11 05:27:55 +08:00
@msg7086 他这样把所有变量都直接改到 memcache 里去,内存根本没用到多少
如果我对代码的理解没错的话,缓存是以整个 list 或者 dict 为单位的 另外我很好奇这个 self.cache 在什么情况下会被回收 说实话,我真心觉得 nfs 上挂 swap 虽然作死,但效果应该不差。 |
12
wangleineo OP |
13
ryd994 2015-11-11 09:52:08 +08:00
@wangleineo 纠结性能是因为你的定位是“分布式内存”,是要解决 OOM ,那性能就是要和物理内存比的。
如果你的定位是“易用的 memcached 客户端”的话,我觉得写的很好。 |
14
canesten 2015-11-11 10:02:31 +08:00
就是 Python 版的 Redisson ?
|
15
wangleineo OP |
16
dreampuf 2015-11-11 10:58:45 +08:00
楼上纠结 RAM+Network 不如 Disk 的诸位
类库封装了 redis 支持多个节点,但是实现比较简单,没有考虑拆分的情况,集群容量还是受最小单节点限制 https://github.com/RealHacker/dmem/blob/master/dbase.py#L19 |
17
wangleineo OP 此图甚好 另外有一个 post http://norvig.com/21-days.html#answers
|
18
mzer0 2015-11-13 00:29:12 +08:00 via iPhone
@wangleineo C 语言实现一个分布式的内存,应该只需要几百行代码;而我认为,先不谈分布式内存的存在意义, redis+python 是不能接受的,硬要说的话,理由是“没有理由”——就是我不想这样做,我宁愿自己编一个。或许某个俄国人实现过,要知道,俄国人最喜欢这些东西了,但我敢肯定没人用。
|
19
GeekGao 2015-11-13 02:04:09 +08:00
感觉没啥适用场景。实际上我用 zookeeper+zmq 实现单机内存统计和消息通信,内存不够或者机器下线,直接把任务交给其他相对大点的内存机器去跑了
|
20
wangleineo OP @mzer0 好吧
|
21
mzer0 2015-11-13 20:34:05 +08:00 via iPhone
@wangleineo 有一种情形我会使用分布式内存:如果两台主机的硬盘数据是自动同步的,主机 A 可以先命令主机 B 加载文件到内存,再通过分布式内存同步到 A 的内存,达到从内存加载文件的目的,减轻硬盘 IO 负担。
|
22
Actrace 2015-11-14 00:19:59 +08:00
内存的存在意义就在于速度。
网络存取,虽然在同一个局域网里,实现了扩大容量的愿景,但是性能肯定不如真正的内存。还不如多买几块 SSD 再做个 RAID 来的实在。 楼主你还是认清事实吧,自行车再怎么快也比不上飞机的(是的,连汽车的速度都无法超越),还是要用正确的工具做正确的事情。 不过这套设计可以用在分布式的持久化存储文件系统上,还是有点意义的。 |
23
wangleineo OP @Actrace 技术是不断发展的,网络存取的速度已经越来越接近内存了,(虽然内存的速度也在提升)。但是硬盘还差好几个数量级,看看上面的图。
|
24
lilin 2015-11-14 20:38:06 +08:00
|