设计遐想---基于Google App Engine的IM

本文详细探讨了聊天应用中的点对点及群聊模式,并深入分析了消息存储、读取等关键技术点。针对不同场景,文章提出了标记模式与置位模式两种解决方案,同时对比了它们各自的优缺点。
聊天模式无非点对点聊天和群组聊天.下面一一来分析.

1. Peer-to-Peer聊天

消息格式:[from, to, body, timestamp, isread].(根据from来识别是个人还是group消息)

消息读取方式
  标记模式
  置位模式

是否要存储: 
  不需要
  需要



[Group Chatting]:

标记模式
每个用户拥有一个timestamp类型的消息游标.(sequence number不利于sharding).
option: 消息携带一个counter, 每被读取一次引用计数就减一.引用计数到0时.消息会删除.
优点: 节省存储空间.
缺点: 实现稍微复杂.

    Non-Persistent
        只需要有一个Expirer, 定期清理超期信息.
    Persistent
        只需要关闭Expirer.


置位模式
需要复制Group Size个副本.获取最近的消息列表: 根据timestamp差值(timespan)和pageSize来获取最近消息列表.
优点: 实现简单
缺点: 浪费存储空间

    Non-Persistent
        用户读取后即删除.
    Persistent
        读取后设置isread为true


权衡
        信息量小
            需要持久化
                可以直接操作db.
            不需要持久化
                可以直接memcache来实现.
        信息量大
            需要持久化
                考虑write-back机制(timeout + 阀值触发).
            不需要持久化
                mem可能不足,仍然考虑write-back机制(timeout + 阀值触发).只不过读取后会删除.
 

在GAE平台上如何考虑
1. GAE memcache为简单key/value型,而消息存取最好是集合操作,也就是需要一个结构化的memcache(比如mongoDB).
2. GAE datastore为Master/Slave模型, 读快写慢,而IM的特征是读写平均. 但是基于GAE的可扩展性, 对于单笔操作而言开销不会随负载增长.
综上考虑, 消息每次直接经过DB.

置位还是标记?
优先选择置位模型.

Group信息在memcache中进行缓存.在DataStore中以StringListProperty的方式保存用户列表.


收发消息Solution 1:
1. 消息直接存入datastore.
2. 先取peer消息.
3. 取Group消息:
  1). 获取用户的所有group(用户所在组的信息也存在于memcache).[complex, fucking thing]
  2). 以groupid为key,去datastore检索消息.[loop]


收发消息Solution 2:
在置位模型下,消息可以保存一个StringListProperty类型的receivers字段.
1. 用户发送消息,根据group id得到用户列表,即为receivers字段取值.存入datastore.
2. 取消息. 对比用户id和receivers来还有时间戳来取消息.

收发消息solution的权衡:
如果群组数量很多,方案1的效率就很差.
如果单个群组的成员很多, 方案2的效率就很差, receivers列表的存储开销就比较明显了.

转载于:https://www.cnblogs.com/OnlyXP/archive/2009/09/01/1558193.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值