MongoDB 笔记
http://www.infoq.com/cn/articles/mongodb-java-orm-bcd
Brian Dilley谈到了MongoDB的几个缺陷;
两个CRM库:
morphia(针对MongoDB的Java库,是类型安全的)
spring-data(Spring Data综合项目的MongoDB实现)
“些ORM库使用了大量注解,出于很多原因,我并不倾向于使用注解,其中最重要的是被注解的对象在多个项目之间的可移植性问题。所以我创建了mongo-Java-orm项目(MJORM,发音为me-yorm),它是针对MongoDB的Java ORM。MJORM使用MIT许可,放在了Google Code上。”
http://www.infoq.com/cn/news/2014/03/crittercism-scaling-billions-req
Mike Chesnut:如何实现每秒30,000次请求
MongoDB文档显示,最常见的拓扑结构是在每一个客户端系统上包含一个路由器——一个mongos进程。Mike Chesnut表示他们开始的时候就是这样做的,并且在很长的一段时间内这种方式工作的很好。
但是随着生产环境中前端应用程序服务器的数量从十几台增长到几百台,Crittercism发现mongos路由和mongod分片服务器之间建立了几百、有时候甚至是几千个连接,负载非常重。这意味着每当chunk平衡(MongoDB分片集群为了保持数据均匀分布所必须使用的平衡措施)发生的时候传送存储在配置数据库中的chunk位置信息都需要花费相当长的时间。这是因为每一个mongos路由都必须清楚地知道每一个chunk都存在于集群中的哪些位置。
通过Chef配置所有的客户端让它们仅与自己区域内的mongos路由通信能够最小化这个问题。
http://www.infoq.com/cn/articles/mongodb-deployment-monitoring
Mat Keep
为了实现低延迟的数据库操作MongoDB中广泛使用了RAM。在MongoDB中,所有的数据都是通过内存映射文件读取和操作的。从内存中读取数据是使用纳秒来度量的,而从磁盘中读取数据则是使用毫秒度量的,所以从内存中读取数据几乎比从磁盘中读取要快了十万倍。
在正常操作期间最频繁访问的数据和索引的集合称为工作集,在理想的情况下它们应该在RAM中。工作集可能是整个数据库的一小部分,例如最近的事件所关联的应用程序数据或者最常访问的热门产品。
MongoDB服务状态命令中包含了一个有用的输出:工作集文档,它提供了一个MongoDB实例工作集的估算大小。运营团队可以按照给定的时间跟踪实例访问的页面数,包括工作集中最旧的文档到最新的文档之间的运行时间。通过跟踪这些指标我们能够发现什么时候工作集会接近现在的RAM限制从而积极地采取行动确保系统是可扩展的。
MongoDB管理服务和mongostat能够帮助用户监控内存的使用情况,下面我们将会对此进行详细地讨论。
大多数MongoDB部署应该使用RAID-10。RAID-5和RAID-6没有提供足够的性能。RAID-0提供了很好的写性能,但是读性能有限,容错能力也不足。部署的MongoDB可以通过副本集(下面将会讨论)提供很强的数据可用性,同时用户应该考虑使用RAID和其他因素满足想要的SLA可用性。
iostat命令可以用于显示高磁盘利用率和过多的写队列。
一个没有建立良好索引就对工作集中的大量文档进行排序和过滤的查询都可能会导致CPU利用率的飙升,但是它们却不会引发磁盘系统问题或者页面错误。
MongoDB的性能通常不会绑定到CPU上。因为MongoDB很少会遇需要利用大量内核的工作负载,比起时钟速度较慢的多核服务器最好的选择是有更快的时钟速度。
扩展数据库——何时扩展和如何扩展?
Sharding可以让MongoDB的部署解决单个服务器的硬件限制而不需要增加应用程序的复杂性,解决的硬件限制包括RAM和磁盘I/O的瓶颈。
在下面的场景中用户应该考虑部署一个分片的MongoDB集群:
RAM限制:系统活动工作集的大小很快就会超过系统RAM的最大容量。
磁盘 I/O限制:系统有大量的写活动,但是操作系统写数据的速度不够快,无法满足需求;同时/或者I/O带宽限制了数据写入磁盘的速度。
存储限制: 数据集接近或者超过了系统中的单个节点的存储容量。
通过运行db.currentOp()命令,你将能够了解集群现在正在执行哪些工作,包括跨分片的文档再平衡。
但是如果复制延迟增长,则可能会引发问题。复制延迟产生的典型原因包括网络延迟、连接问题和磁盘延迟(例如二级节点的吞吐量劣于主节点)。
复制状态和复制延迟可以通过replSetGetStatus命令重新恢复。
服务 (MMS)
MongoDB管理服务(MMS)提供了云监控和备份服务,帮助用户优化集群、解决性能问题、减轻运维风险。
MMS监控支持图表、自定义仪表盘和自定义警告。MMS仅需要最低限度的安装和配置。用户在所有的MongoDB实例上安装一个本地代理,该代理会跟踪与数据库使用情况相关的数百个关键的健康指标,包括:
操作数(Op Counters)—每秒钟执行的操作的数量
内存(Memory)—MongoDB正在使用的数据量
锁百分比(Lock Percent)—写锁消耗时间的百分比
后台刷新(Background Flush)—将数据刷新到磁盘消耗的平均时间
连接(Connections)—MongoDB当前打开的连接的数量
队列(Queues)—等待运行的操作的数量
页面错误(Page Faults)—磁盘的页面错误数
复制(Replication)—主节点操作日志的长度以及复制延时
日志(Journal)—写入日志的数据量
Munin node是一个开源软件程序,它可以监控硬件并报告磁盘和RAM的使用情况这样的指标。MMS能够收集Munin node产生的这些数据,并在MMS仪表盘中将这些数据和其他数据一起展现给用户。因为每一个应用程序和部署都是唯一的,所以用户应该为磁盘利用率的峰值、网络活动的主要变化和平均查询长度/响应时间的增长创建警报。
MongoDB提供了一个性能分析工具,该工具能够记录数据库操作相关的细粒度信息。分析工具可以记录所有事件的信息,也能够只记录那些持续时间超出了配置阈值的事件的信息。分析数据存储在一个固定集合中,用户能够很容易地从中搜索相关的事件——查询这个集合可能比尝试着去解析日志文件更加容易。
其他的监控工具
有各种各样的监控工具让你能够从其他的方面深入理解MongoDB系统。
mongotop 是随MongoDB提供的一个工具,它能够跟踪并报告一个MongoDB集群当前的读、写活动。
mongostat 是随MongoDB提供的另一个工具,它为所有的操作提供了一个全面概览,包括更新、插入的计数,页面错误、索引的丢失情况以及很多其他的关系到系统健康的重要指标。
Iostat、vmstat、netstat和sar这样的Linux工具也能为深入探索MongoDB系统提供有价值的信息。
对于Windows环境上的用户而言,性能监控器(Performance Monitor,一个Microsoft管理控制台单元)是一个非常有用的工具,可以用来测量各种指标。
个基础的MongoDB配置文件类似于下面的内容:
fork = true
bind_ip = 127.0.0.1
port = 27017
quiet = true
dbpath = /srv/mongodb
logpath = /var/log/mongodb/mongod.log
logappend = true
journal = true
http://www.infoq.com/cn/news/2014/03/10-things--know-mongodb
你可能并不希望系统随着使用量的增长出现性能扩展障碍。 根据大量用户的部署经验,性能瓶颈通常是(按顺序):
应用程序访问模式没有使用最优的模式设计
索引不佳或者缺失索引,抑或有太多不必要的索引
磁盘较慢/磁盘IOPS不足
索引没有足够的RAM
http://www.infoq.com/cn/articles/depth-study-of-Symfony2
可能的技术方案
基于MySQL数据库
采用GeoHash索引,基于MySQL
MySQL空间存储(MySQL Spatial Extensions)
使用MongoDB存储地理位置信息
SELECT id, ( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians
( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance
FROM places HAVING distance < 25 ORDER BY distance LIMIT 0 , 100;
SQL语句可以简化如下:
SELECT * FROM places WHERE ((lat BETWEEN ? AND ?) AND (lng BETWEEN ? AND ?))
GeoHash是一种地址编码,通过切分地图区域为小方块(切分次数越多,精度越高),它能把二维的经纬度编码成一维的字符串。
db.runCommand( { geoNear: "places", near: [ 121.4905, 31.2646 ], num:100 })
/**
* @MongoDB\Document(collection="places")
* @MongoDB\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
* @MongoDB\Indexes({
* @MongoDB\Index(keys={"coordinate"="2d"}),
* @MongoDB\Index(keys={"coordinate"="2dsphere"})
* })
*/
我们用到的代码包是doctrine/mongodb-odm-bundle(下文称ODM),这个代码包提供了在Symfony2环境下的MongoDB数据库支持,使用这个代码包,可以让我们更加方便的在Symfony2环境下操作MongoDB数据库。
http://blog.nosqlfan.com/html/1811.html