MongoDB开发应用实践


吃蟹 视觉中国的 MongoDB应用实践 QCon beijing 2011 插图 : http://czone.chinavisual.com/art/4b4501548f47e8ef73699a0c.html 111年4月1日星期五 About.me • 潘凡 ( nightsailer) 视觉中国 • @nightsailer //twitter,sina,linkedin, github ... • nightsailer # gmail.com • http://nightsailer.com/ 211年4月1日星期五 为啥用 MongoDB 赶 NoSQL时髦 ? Auto-shard等激动人心的特性 ? • No! 08年,还都是浮云 最初的想法是寻找一个可靠的分布式 K/V 解决 MySQL的问题 311年4月1日星期五 原来的架构 • MySQL( Percona), Master-Master-Slaves • HA:MMM M y s q l ( M a s t e r - M a s t e r ) Mysql(M1) Mysql(M2) Slave Slave MMM App 411年4月1日星期五 新要求 • 能够适应多数据源 • 需要灵活,不确定的 schema • 不同模型的字段不定,属性不定 • 属性更新频繁 • 服务器等硬件资源有限 511年4月1日星期五 如何解决? 原有 MySQL的方案 * 使用文本字段, JSON存储 • schema自由度高 • 更新容易,直接检索困难 * 使用关联表 • schema自由度有限,类型控制 • 更新频繁, query缓存失效 611年4月1日星期五 新思路 Mysql(M1) Mysql(M2) Slave Slave MMM/vdb11 App K V KV1 KV2 711年4月1日星期五 新思路 继续使用 Memcached? • 缓存失效,内存不足 决定:寻找 Memcached替代品 • 能够持久化的分布式 KV 811年4月1日星期五 选型条件 • 同时有 PHP/Perl的良好客户端支持 • 性能和 Memcached相差不要太多 • 支持分布式集群 • 低碳环保,节约资源 • 文档清晰,有成功案例 911年4月1日星期五 一些候选者 • Flare • Repcached • Redis • TC/TT 1011年4月1日星期五 最初的选择 选中 Flare • 内置 cluster看起来很美好 ,可靠性有保 证 • 使用 Memcached协议,现有改动小 1111年4月1日星期五 代价 项目开发 1个月后 • 官方更新显示似乎并非如此可靠 • 水土不服: • 个人能力有限,无法解决一些灵异事 件 • 没有开发者社区 • 不懂日文 ;-( 1211年4月1日星期五 新的候选者 • Cassandra • 技术实力无法支撑,用不起 • CouchDB • 灵活,但性能口碑似乎不佳 1311年4月1日星期五 重新选择 MongoDB • 读写性能中庸,比 Redis逊色 • Document模型令人满意 • 内置操作没有 Redis惊喜,基本够用 • MySQL类似的集群机制 ,上手方便 • 某些 MySQL的优化部署经验可以复用 1411年4月1日星期五 胆子再大一点 MySQL + MongoDB? • 多余:很多 MySQL的操作 MongoDB均 可实现 • 同时维护 MySQL <=> MongoDB 的数 据,代码逻辑有些复杂 • 人员流失,培训新人表示鸭梨大 1511年4月1日星期五 胆子再大一点 能否彻底抛弃 MySQL • Transaction?可以没有 • Joins? 原本少用,可以没有 • 数据一致性:不太高 1611年4月1日星期五 胆子再大一点 好吧,试试 • 拿一个旧项目开刀 • 1人 1个星期完成 90%代码移植 • 原有 35个 table => 10 collection • 开发过程很 happy! 1711年4月1日星期五 MongoDB,就是它了 一举两得的加分项: GridFS • 简单,符合我们的要求 • 无需再考虑分布文件系统 • 放弃了原来的 MogileFS,减轻运维压 力 1811年4月1日星期五 MongoDB,就是它了 选对了 • SourceForge等一些大站应用增强信心 • 分享的信息逐渐丰富 • 10gen核心团队在 mailing-list快速响应, 有问必答 • NoSQL开始受到追捧, MongoDB的口 碑良好 1911年4月1日星期五 应用案例 1 • 评论 comments:{ _id:ObjectId(‘xxx’), art_id:2, content: ‘呼呼 真是 ...’, replied_on: 12233 created_on: 12222 replies: [{ _id: ObjectId(‘xxx’), content: ‘哈哈 ,谢了 ...’, replies:[] }]} 2011年4月1日星期五 应用案例 2 用户动态 /新鲜事 : • 关注的用户的动态 • 个人作品的新动态 • 关注的作品的新动态 (评论过 /收藏过 /打分 过 ...) • 可取消对特定事件的 订阅 2111年4月1日星期五 应用案例 2 推送模式的实现 • db.activity_stream.feed (订阅事件) • db.activity_stream.user(用户动态汇总 ) • db.activity_stream(动态详细信息) 2211年4月1日星期五 应用案例 2 feed的优化 • 区分热门用户和普通用户 • 热门用户的 follower使用独立的 collection • 普通用户使用 embed list 2311年4月1日星期五 应用案例 3:全文检索 尝试 1: Regex • 无索引,慢! 尝试 2: Sphinx • 手动生成 xml,刷新重建索引 • 无法增量索引 2411年4月1日星期五 应用案例 3:全文检索 尝试 3: 分词+ Array/List 查询 ($all) • 简单,够用 • 分词: PHP-SCWS(谢谢!) • 增量索引 : • 无侵入索引过程:从 oplog读取,解 放应用端 2511年4月1日星期五 准备部署 手动编译 MongoDB • Scons, 要懂点 Python • 升级 boost(CentOS) • static link mongod • 使用 tcmalloc 2611年4月1日星期五 准备部署 • 手动编译 MongoDB( ICC编译选项) COMMON_CXXFLAGS='-fp-model source -unroll2 -axSSE4.1,SSE4.2 -xSSE3 - static-intel -fpic -fno-strict-aliasing' CXXFLAGS="-O3 -ipo -static-libgcc $COMMON_CXXFLAGS" scons --release --static --extrapath=/opt/local --cxx=$CXX --icc -- extralib='tcmalloc_minimal' --icc-cxxflags="$CXXFLAGS" --icc- cppflags="$CPPFLAGS" -c $BIN_SERVER scons -j4 --release --static --extrapath=/opt/local --cxx=$CXX --icc --extralib='tcmalloc_minimal' --icc-cxxflags="$CXXFLAGS" --icc- cppflags="$CPPFLAGS" $BIN_SERVER 2711年4月1日星期五 准备部署 • 定制编译麻烦,但是相对稳定,问题很 少(不仅仅是心理安慰) • 缺点:无法及时更新编译,只针对性的 升级 2811年4月1日星期五 准备部署 • 磁盘: 使用 Raid10 • 文件系统: • XFS • Ext4 (?) 2911年4月1日星期五 部署 开始, 2009/6, 版本: 0.9/1.0 • 1 Master + 2 slaves • 1m 初始数据 • 20g存储 • Dell 2850/4g(Master)+ 2*Dell 2950/4g(公用) MongodMaster) Nginx PHP-FPM MongodSlave) Gearman-workers Gearman-workers 3011年4月1日星期五 备份 * 使用独立 Slave方式备份 • 慢,不影响 * lvm snapshot • 快,客户端瞬时无法写 • fsync & lock db * mongodump? • 速度慢+空间浪费+恢复慢 3111年4月1日星期五 监控 • mongostat / vmstat / iostat • collectd(我们使用这个) • 自定义 : json-rest+perl plugin • 其他: Munion / Nagios ... 3211年4月1日星期五 美好的时光 MongoDB不是重口味 • CPU友好,几乎无负担 • 内存需要足够放下索引, 4G以上为佳 • 可以和磁盘 IO不高的应用混搭 插图 :http://czone.chinavisual.com/art/4c7918b74979590970b80000.html 3311年4月1日星期五 美好的时光都是短暂的, 6个月后 开始有点问题了 插图 :http://czone.chinavisual.com/art/4b45015496ddabef73f49197.html 3411年4月1日星期五 空间使用率 磁盘空间不足,纪录没有显著增长, Why? • 应用执行操作: Map/Reduce删除 /重新 插入 • 删除空间不能回收(早期版本) • 可复用但频繁更新导致碎片( 1.6+) • 检索时间加长 ** 定期 reIndex或 repairDatabase, 3511年4月1日星期五 故障 0:开发版的血案 * MongoDB 宕机 • Out of Memory! • 新版本 v1.3某些情况出现内存泄露 * 服务端 cursor过多 • Perl driver的 bug, 修复 3611年4月1日星期五 故障 0:开发版的血案 教训 1: • 永远别用开发版,即使天大的诱惑 • 谨慎使用稳定版的头 2个小版本 教训 2: • 选用了一个语言,团队内就要有人熟 悉对应的 driver代码 • 自己实现一个 driver是个不错的想法 3711年4月1日星期五 故障 1:50x的烦恼 502 Bad Gateway * GridFS的问题? • 使用 Perl Plack替换=》 好转 * 减少 GridFS的读取 • Nginx proxy_store • 不是最优,但简单, 够用 NginxStarman/Plack MongoDB Disk Cache Proxy store 3811年4月1日星期五 故障 1:50x的烦恼 504 Gateway timeout • 灵异:开发环境无法重现 • 无规律,白天或晚上均会出现 • Perl救场:根据 nginx_errorlog的时间 抽取前后 5分钟内 mongodb.log日志 • 找到元凶:空间分配延时导致 client端 超时 3911年4月1日星期五 故障 1:50x的烦恼 教训 3 • 使用 XFS等支持 pre-allocation的 FS • 提前预分配数据文件: for i in {1..50} do echo $i head -c 2146435072 /dev/zero > $db.$i done 4011年4月1日星期五 故障 2: 空间使用 • Mongod crash • 磁盘空间不足, Why? • 应用执行操作: Map/Reduce删除 /重新 插入 • 删除空间不能回收 4111年4月1日星期五 插图来自 : http://czone.chinavisual.com/art/4cad0e08497959d621a10000.html 4211年4月1日星期五 第一次灾难 • 机房电源空开跳闸 • 10台服务器全部遇难 • MongoDB无法启动 • 尝试 Repair~ 5小时后失败 • 从备份中恢复 • 丢失了 10小时数据!! 插图来自 : http://czone.chinavisual.com/art/4cad0e08497959d621a10000.html 4211年4月1日星期五 第一次灾难 • MongoDB的致命缺陷: • 单机可靠性低 • cluster可靠性 : 通过 slave复制保证 • 部署时没有考虑机房断电的特殊情况 4311年4月1日星期五 亡羊补牢之 1 • 缩短磁盘刷新间隔 --syndelay • 60s(default) => 15~30s • 磁盘 IO受到影响,可接受 • 应用端批量写入后调用 fsync • 写入速度降低 4411年4月1日星期五 亡羊补牢之 2 • 升级到 1.6.3,转换 Master-Slaves到 RelicaSets • 1 Primary + 2 Secondary • 服务器升级到 4g-8g内存 • 应用端同时使用 w=2参数 • 写入速度降低 4511年4月1日星期五 教训 5 • 我们很业余 • 安全第一 • 要考虑极端条件下的容灾和数据安全 • 完整的离线备份总是你最后的救命稻草 4611年4月1日星期五 然而,还没有结束。。。。 插图 :http://czone.chinavisual.com/art/4bd19d3b4979593e1a350000.html 4711年4月1日星期五 故障 4: RS fail-over失效 • MongoDB 不可用 • Primary维护期间不小心 kill了第 2个 secondary • 剩余的 secondary未能正常接管 4811年4月1日星期五 故障 4: RS fail-over失效 解决: • 增加 2个 Arbitor • $ mongod --bind_ip 127.0.0.1,192.168.8.10 -- replSet rs10 --oplogSize 1 ... • > rs.addArb(‘192.168.8.10:27020’) • ... 4911年4月1日星期五 故障 4: RS fail-over失效 教训 6: 这才是完整的 ReplicaSet • 1 Primary + 2 Secondary + n Arbitor • 文档中语焉不详的往往是你最被忽视 的,把它搞清楚 • 避免手动维护,使用事先写好的脚本 5011年4月1日星期五 又一次断电了! • 6个月后, “又 ”一次出现断电 • 这次是修空调拉错闸 ;-( • 临时工不好当 • 重启后, ReplicaSet集群 fail-over到一个 secondary,中间过程无干预 • Primary 无法启动 ,仍需要修复! • 还好! 5111年4月1日星期五 1.8的改进 • 1.8提高了单机可靠性的一个措施 • journaling file • mongod -dur • 避免 crash后必须 repairDatabase • 初步测试,效果尚可,准备稳定后升级 5211年4月1日星期五 有了新需求 • GridFS的新需求 • 能够存储较大文件(高清图片,压缩 包) 10mb-500mb不等 • 允许用户使用多线程下载 5311年4月1日星期五 问题 • GridFS大文件的分发 • 不能使用 Nginx proxy_store加速 • MongoDB读取负担加大 • 并发链接增加 ,Plack app响应速度下降 • prefork模式有限制 5411年4月1日星期五 措施 • GridFS文件分库 • 缩略图,高清图片+大文件 • 读写分离( slaveOK) • 将 Plack app部署到 Tw i g g y( AnyEvent), 解决高并发链接的问题 5511年4月1日星期五 R S 0 2 R S 0 1 127.0.0.1:9004 127.0.0.1:9003 127.0.0.1:9002 127.0.0.1:9001 Nginx Starman Gearman Sencondary Twiggy/PSGI Starman workers/PSGI (slaveOK) 5611年4月1日星期五 带宽不够用了 • 下载太消耗带宽 • 国外的服务器和带宽都便宜 • 怎么同步? 5711年4月1日星期五 理想 • 国外使用一个 Slave only的 MongoD节点 • priority = 0 • VPN链接 2个数据中心 I D C I D C Primary Slave1 Secondary1 ReplicaSet1 VPN Secondary2 5811年4月1日星期五 现实 • 超高的网络延时 >300ms • MongoDB 启动失败,无法完成初始化 5911年4月1日星期五 折腾 • 解决 MongoDB延迟启动 • 将 snapshot手动复制到国外 • 手动作复制工作 • 监控 local.oplog.rs (使用 tailable cursor) • 压缩后发送到国外节点 • 接收端接收后 replay oplog 6011年4月1日星期五 失败! • 运行了 2个月,暴露的问题: • GridFS数据传输较大,复制延迟时间较 高 • 墙让 VPN不时抽风 6111年4月1日星期五 调整 • 放弃集群和 VPN • 将 GridFS本地导出压缩后传送到国外 • 仅仅将需要更新的数据更新到国外 • BSON压缩,使用 HTTP协议+多点续 传 • 国外使用普通的 mongod 6211年4月1日星期五 教训 7 • 小心陷入思维定式 • 太华丽 == 不现实 • 不要忽视最土鳖的做法 • 灵活运用不同的 unix工具 插图 : http://czone.chinavisual.com/art/4c05e7be4979596b7e570000.html 6311年4月1日星期五 Auto-sharding • 1.6GA 内置了 Auto-sharding • 有诱惑,尝试 • 2套方案并行 1个月 • 从原有生产系统导入数据 • 并行写入测试集群 6411年4月1日星期五 测试结果 • Shard_key的烦恼 • 单一 shard key导致 chunk分配不均衡 • 类似 4sq案例 • 复合 shard_key需要修改现有的应用端 • counting 不准 • 务必减少 chunk的移动 • balancer的稳定性,也不够智能 6511年4月1日星期五 测试结果 • 结论: • 从现有非 shard环境升迁是很痛苦的过 程 • 如果最初就是 shard,相对容易 • 维持现有的手动分片机制 • 等待 1.8成熟,新项目可以考虑使用 6611年4月1日星期五 无责任小结 • 市场宣传亮点和实际会有差距 • MongoDB的 auto-shard目标感觉很好 • GA和完全成熟可靠多少还有些差距 • 2.0+ ? 6711年4月1日星期五 MongoDB其他小结 • 多数 MySQL的 Web应用均能胜任 • Schema free,大大提升开发效率 • Geo搜索降低位置服务门槛 • MySQL优化的一些经验可以复用 • GridFS能够胜任中小规模的文件系统 • 千万级别的数据量完全无需做 sharding • Auto-sharding注意 shared_key和 balancing 的过程,建议 1.8/2.0以后使用 6811年4月1日星期五 谢谢大家! Question? 插图来自 :http://czone.chinavisual.com/art/4b45015461be3def730e6351.html 6911年4月1日星期五
还剩69页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 4 人已下载

下载pdf

pdf贡献者

sensejw

贡献于2011-10-13

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf