mongodb in sns
DESCRIPTION
MongoDB Beijing Meetup on May 7th.TRANSCRIPT
刘 祥 超 0 5 / 0 6 / 2 0 1 1
SNS 中的 MONGODB
个人介绍
• Iwind – 架构师• RockMongo – MongoDB 管理软件 http://
code.google.com/p/rock-php• PHP+MongoDB• 将近一年的版本更新• 9 种国际化语言• Windows/MacOS/Unix 的集成环境• 7 committers and contributors
• 欢迎合作开发社区和游戏产品• 联系方式:• Gmail: [email protected]• QQ: 19644627
WHY MONGO
• MongoDB vs RDBS• MongoDB vs other NoSQLs• 文档模型的优势
MONGODB VS RDBS
• RDBS• 稳定和健壮• 成熟的解决方案• 结构分散,查询繁琐• 效率低下
• MongoDB• 快速发展当中,不够成熟• 新的编程模式• Key/value• 高存储和读写效率 • 安装、维护、扩展容易
MONGODB VS 其他 NOSQL
• 其他 NoSQL• 存储对象间关系较弱• Set/get 速度极快• 适合做缓存
• MongoDB• 支持存储对象间的查询• Group/distinct• MapReduce• 驱动较全 C/C++/Java/PHP/node.JS /Scala…• Set/get 稍弱• 适合做存储
MONGODB 文档模型的优势
• BSON• Encode/decode 快,在 PHP 中• 比 json 速度快 30%• 比 serialize 速度快 100%
• JSON• 易于学习• 一次性读取一组信息• 容易集成到其他系统中• 使用嵌套对象减少集合数量
SNS 中的技术特点
• 以用户为中心• 高并发• 写操作频繁• 服务稳定性• 高扩展性• 即时功能• IM• 消息
特点 - 以用户为中心
• 索引• 以 uid 为第一过滤条件
特点 – 高并发
• Replica Set http://www.mongodb.org/display/DOCS/Replica+Sets• 读写分离、分布: slaveOkay
特点 – 写操作频繁
• Replica Set
特点 - 服务稳定性
• Replica Set• 数据冗余• 故障转移• 热维护• 故障恢复:• delayed secondary - slaveDelay
特点 – 高扩展性
• Sharding• http://www.mongodb.org/display/DOCS/Sharding• maxSize
特点 – 即时
• MongoDB 可以支撑长连接• 配合 Memcache
设计原则
• 效率• 简单• 限制
设计原则 – 效率
• 优先选择效率高的方案• 保留扩展的可能
设计原则 – 简单
• 简化数据结构• 制定通用的规则• 命名• 集合设计模式
• 不考虑未知的需求• 尽可能减少字段• 尽可能聚合而非拆分
设计原则 – 限制
• 只使用 MongoDB 作为存储数据库• 只考虑在 Linux/Unix 下的运行效率• 只考虑 Nginx 下的优化• 只支持某一种开发语言• Java• PHP
• 对 SNS 做出限制• 只考虑 1000 条数据• 允许数据显示的延迟 (<10s)
• 特殊问题特殊对待
SCHEMA
• 仅供参考• Map: { … }• List: [ … ]
常用模式
• 自定义函数• 模版模式
自定义函数 – SYTEM.JS
• 在控制台上操作
• 参考 RockMongo
自定义函数
• 实际应用中不会明显提升效率• 简化程序• 可以根据关联集合过滤数据• 可以一次性取出多个集合的数据• 可以批量提交更新• 由于效率问题,不应该只使用 $where
自定义函数 - 示例
模版模式
• 分离数据和显示• 易扩展和维护• 体积小
存储
渲染
SNS 常用功能的设计
• 好友• 新鲜事• 在线状态• 访问统计• 聊天会话• 事件
好友设计
• 一次性读取 list• $slice 分页• 公共的好友:• Intersect($list1, $list2)
• 好友的好友(可能认识的好友)• $diff = Diff($list1, $list2)• $diff = Diff($list1, $list3)• …• Top(group($diff))
• 方便分组
新鲜事设计 - 1
• 样式各异• 只需要保留最近的
新鲜事设计 - 2
• 设计
• 查询 $in
在线状态设计
• State• 0 离线• 1 在线
• 放在 users表中
在线状态 – 查询
• 状态• 离线: online.state=0||updated_at<最近五分钟• 离开: online.state=1 && updated_at>最近五分钟• 在线: online.state=1 && updated_at>最近 1 分钟
• 列表• 在线的好友:• db.users.find({ “uid”: {$in: [friends], “ 在线” :1 } })
• 在线的人的资源:• is_online 函数:在 online 中查询 db.users表• db.resources.find({ $where: “is_online(this.uid)” })
在线状态 – 更新
• comet轮询中更新
访问统计设计
• 日统计• 月统计• 总访问数• $addToSet• 查询
聊天会话设计
聊天会话 – 对象
• 会话人 – connections• 会话 – conversations• 消息 - messages
聊天会话 – 设计
聊天会话 – 查询
• 通过 conversation_id 将两人联系起来,理论上是多人的• 查询 user_connections 取得正在会话的人• 查询 user_conversations 查询当前会话的状态• 查询 user_messages 查询会话的消息• 每个消息两份,可以单方面删除或清空
事件设计
事件源 控制中心 订阅者事件
事件 – 查询
• 订阅事件 $addToSet events• 发布事件 • $set list.事件类型 :事件数据• $set updated_at_ms
• 查询事件• comet 长轮询• 先检查 updated_at_ms• 再取数据
总结
• 减少查询,尽可能一次到位• 减少查询的字段数• 在对象中多使用嵌套的 Map/List• $addToSet 减少查询
配合工具
• 目的• 减少查询• 用更适合的工具做不同的事情• Memcached 比 MongoDB 快 2~3倍
• Nginx• Fastcgi cache
• Memcached• 分布式的内存缓存
• 共享内存• 内存缓存,比 Memcached 快 3~4倍
MongoDB
MemcachedShare
Memory
Nginx
THANKS
•Thanks