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