一个MQ,开5个线程,平均一天消费数据如下:
总表:249733 (upsert + $inc)
子表:1732389 (insert)
在数据量插入到这个级别的时候,数据库插入就有延迟了,延迟时间在5分钟以上,逐渐增大...
jstack <pid>走一发,看MQ消息线程状况,5个线程都是如下状况:
"main" prio=10 tid=0x00007f38ac009000 nid=0x1359 runnable [0x00007f38b3723000] java.lang.Thread.State: RUNNABLE at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398) at java.net.ServerSocket.implAccept(ServerSocket.java:530) at java.net.ServerSocket.accept(ServerSocket.java:498) at org.apache.catalina.core.StandardServer.await(StandardServer.java:470) at org.apache.catalina.startup.Catalina.await(Catalina.java:781) at org.apache.catalina.startup.Catalina.start(Catalina.java:727) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
注意其中一句话:java.lang.Thread.State: RUNNABLE
这表示线程正在运行,如果5个都这样,直白点就是线程繁忙。
此时,还不能确定问题所在,但要解决这个问题可以有三个方案,也可并行这三个方案:
1、增加MongoDB索引
2、增加消费线程数。(5->15)
3、将消息处理OnMessage内处理程序改为异步(即走线程池模式)
这三个方案,最快实施的则是方案1,于是方案1走一波,为了验证是否因索引导致,我们开启MongoDB慢日志,命令如下:
db.setProfilingLevel(1 ,50);
其中第一个参数:
0 – 不开启
1 – 记录慢命令 (默认为>100ms)
2 – 记录所有命令
第二个参数:
n,慢操作执行时间,单位ms
执行成功后,系统会在DB下生成一个系统表
system.profile
这个表的结构如下:
{ "op" : "update", "ns" : "chae_prod.oma_osoa_link_total", "query" : { "$and" : [ { "nsCode" : { "$eq" : "lyf" } }, { "envCode" : { "$eq" : "prod" } }, { "minuteTime" : { "$eq" : "2017-06-29 10:09" } }, { "clientServiceName" : { "$eq" : "back-order-web" } }, { "serviceName" : { "$eq" : "basics-stock-service" } } ] }, "updateobj" : { "$set" : { "clientServiceName" : "back-order-web", "nsCode" : "lyf", "envCode" : "prod", "minuteTime" : "2017-06-29 10:09", "belongDate" : "2017-06-29", "serviceName" : "basics-stock-service" }, "$inc" : { "successTotalNumber" : 1, "totalNumber" : 1, "failedTotalNumber" : 0 } }, "keysExamined" : 0, "docsExamined" : 213026, "nMatched" : 1, "nModified" : 1, "keyUpdates" : 0, "writeConflicts" : 0, "numYield" : 1669, "locks" : { "Global" : { "acquireCount" : { "r" : NumberLong(1670), "w" : NumberLong(1670) } }, "Database" : { "acquireCount" : { "w" : NumberLong(1670) } }, "Collection" : { "acquireCount" : { "w" : NumberLong(1670) } } }, "millis" : 631, "execStats" : {}, "ts" : ISODate("2017-06-29T10:19:58.387+08:00"), "client" : "10.10.254.15", "allUsers" : [], "user" : "" }
其中millis字段表示执行时长,我们看到631MS,好高啊。
OK,我们迅速实施增加索引动作
我们在主表上增加upsert的query索引(也是前台查询索引):
{ "nsCode" : -1, "envCode" : -1, "minuteTime" : -1, "clientServiceName" : -1, "serviceName" : -1 }
在子表上增加前台查询索引:
{ "nsCode" : -1, "envCode" : -1, "endTime" : -1, "clientServiceName" : -1, "serviceName" : -1 }
增加完后,我们再查询数据,发现order最新时间的数据,OK出来了,和现在时间对的上了。
再来看一下内存stack:
"pool-2-thread-1" daemon prio=10 tid=0x00007f385ce3c800 nid=0x1370 waiting on condition [0x00007f38a14f7000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000c6bd5740> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745)
“TIMED_WAITING (parking)”中的 timed_waiting 指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。
这就表示我们的线程消费已经处于挂起状态了,比较清闲,等着自动回收了。
观察一段时间后,发现没有什么大的问题。
于是我们便不再执行2,3方案。
为了保险期间我增加了方案4:
方案4:删除历史数据
有两种方法实现方案4,一个是用 MongoDB自带的TTL,具体语法列一下,剩下的请度娘:
db.log_events.createIndex({
"createdAt"
: 1},{expireAfterSeconds: 180}) #5分钟后过期
后面的参数单位是秒,180秒。
由于我们默认给MongoDB分配的是1G内存,我们还对 MongoDB内存进行了加大,增加到2G。
另一种就是你自己写JOB定时删了。好了方案优化到此结束。
期待与大家分享更多的MongoDB运维优化方案
相关推荐
本书的标题提到了“权威指南”,这意味着内容会非常全面和深入,涵盖了MongoDB的基础知识、安装配置、核心操作、高级特性、性能优化、安全机制、运维监控等各个方面。书中的内容应该包括但不限于以下方面: 1. 数据...
这些最佳实践关注于MongoDB Atlas作为数据库即服务(DBaaS)的部署和操作,包括如何在MongoDB Atlas上实现高性能和最佳的运维实践。 MongoDB Stitch: 后端即服务 MongoDB Stitch作为后端即服务(BaaS)提供者,为...
数据库管理是MongoDB运维的核心工作,这部分内容介绍了如何进行用户权限管理、备份恢复、性能监控等。 ### **34. MongoDB概念和术语(Mongo Concepts and Terminology)** 这部分内容定义了MongoDB中常用的概念和...
版本7.0.8是该工具的一个更新版本,提供了一系列增强的功能和优化,旨在提高开发人员和数据库管理员的工作效率。 NosqlBooster 4 MongoDB的主要特点包括: 1. **图形化用户界面**:它提供了一个直观的GUI(图形...
首先,MongoDB 4.0系列引入了混合交易(Hybrid Transactions),这是一项基于ACID(原子性、一致性、隔离性和持久性)原则的重要更新。这种新的事务处理能力使得MongoDB能够处理复杂的业务逻辑,提供跨文档的一致性...
在 MongoDB 4.0 系列中,最重要的特性之一是引入了交易(Transactions),支持多文档ACID事务,这使得 MongoDB 更适合处理复杂的业务逻辑,尤其是在金融、电子商务等领域。在 4.0.22 版本中,可能已经对事务处理的...
在这个版本中,MongoDB引入了一系列的功能更新、性能优化和安全改进。 首先,让我们关注MongoDB的分片特性。在4.2.5版本中,MongoDB支持水平扩展,允许数据分布到多个分片上,以处理大量数据并提供高可用性。这使得...
这里我们关注的是 MongoDB 的 4.2.2 版本,它包含了一系列改进和新特性,旨在提供更好的性能和功能。 首先,让我们了解一下 MongoDB 的核心概念。MongoDB 使用 JSON 格式的文档(BSON)来存储数据,这种格式允许...
#### 二、MongoDB 安装指南 **2.1 支持的平台** MongoDB 支持多种操作系统,包括但不限于: - Windows(Server 2008 R2 及以上版本) - Linux(Ubuntu、CentOS、RHEL 等) - macOS(OS X 10.7 及以上版本) **...
这个版本的MongoDB在2017年发布,提供了一系列增强的功能和性能优化。 MongoDB的主要特性包括: 1. 文档型数据模型:MongoDB以JSON格式的文档作为存储单元,这使得数据结构灵活,易于理解和操作。 2. 分片集群:...
8. **性能优化**:MongoDB提供了多种方式来优化性能,包括调整硬件资源分配、索引设计、查询优化等。 9. **监控与日志**:MongoDB的日志文件可以提供运行时的信息,帮助诊断问题。同时,通过监控工具,如MongoDB的...
数据库运维是IT领域中的一个重要组成部分,它涉及到对数据库系统的安装、配置、监控、优化、备份、恢复以及安全性管理等一系列工作。在"数据库运维2022版形考任务"中,我们可以推测这是一份针对国开教育计算机网络...
此外,定期检查MongoDB的日志文件以及进行性能优化和数据备份也是维护的重要部分。 以上就是在Linux环境下安装MongoDB 4.0.0的基本步骤。理解并熟练掌握这些步骤对于管理和运维MongoDB数据库至关重要。
MongoDB在3.0.2版本中提供了一系列的重要特性和改进,使其在大数据管理和分布式系统中表现出色。 首先,MongoDB 3.0.2在性能方面进行了优化。它引入了新的存储引擎——WiredTiger,相比于之前版本的MMapV1,...
Eliot Horowitz,MongoDB的联合创始人和CTO,在引言部分阐述了MongoDB的设计理念,即从现实世界的需求出发,解决传统关系型数据库存在的问题,并利用文档型数据库的数据模型提供一系列新的功能。 首先,MongoDB的...
索引是数据库性能优化的关键技术之一,本书中对MongoDB的索引创建和管理做了详细说明,包括如何建立单个字段索引、复合索引、地理位置索引等,以及如何通过索引优化查询速度。 聚合工具是MongoDB处理大量数据时的...
`mtools` 提供了一系列脚本,帮助用户便捷地创建和配置MongoDB实例,包括启动、停止、复制集配置、数据导入导出等操作。这些脚本简化了繁琐的手动配置,使得开发者可以更专注于应用的开发和测试,而不是数据库的运维...
2. **集合与文档**:在MongoDB中,数据库由一系列集合构成,集合又包含多个文档。这种结构类似于关系数据库中的表和行,但不需预定义模式,便于快速开发和迭代。 3. **查询语言**:MongoDB使用一种名为MQL(MongoDB...
总的来说,NoSQL Manager for MongoDB 3.8.2.4是一个强大而全面的MongoDB管理工具,它简化了数据库的日常管理任务,提升了开发和运维效率。无论是初学者还是经验丰富的数据库管理员,都能从中受益。
- 通过实施这一系列措施,有效地降低了使用MongoDB的风险,同时规范了使用方式,扩大了使用范围,并提高了使用水平。 - 架构规划方面,我们协助制定了明确的标准和规范,确保了MongoDB在项目中的合理应用。 - 开发...