我如安在SQLServer上天天处理赏罚四亿三万万记录语言&工具

来源:互联网 / 作者:SKY / 2017-12-01 05:29 / 点击:
起首声明,我只是个措施员,不是专业的DBA,以下这篇文章是从一个题目的办理进程去写的,而不是一开始就给各人一个正确的功效,假如文中有差池的处所,请列位数

起首声明,我只是个措施员,不是专业的DBA,以下这篇文章是从一个题目的办理进程去写的,而不是一开始就给各人一个正确的功效,假如文中有差池的处所,请列位数据库大牛给以指正,以便我可以或许更好的处理赏罚此次营业。

项目配景

这是给某数据中心做的一个项目,项目难度之大怒不可遏,这个项目真正的让我感受到了,阛阓如沙场,而我只是个中的一个小兵,太多的战术,太多的高层之间的较劲,太多的黑幕了。详细这个项目标环境,我有空再写相干的博文出来。

这个项目是要求做情形监控,我们临时把受监控的装备称为收罗装备,收罗装备的属性称为监控指标。项目要求:体系支持不少于10w个监控指标,每个监控指标的数据更新不大于20秒,存储耽误不高出120秒。那么,我们可以通过简朴的计较得出较抱负的状态——要存储的数据为:每分钟30w,每个小时1800w,也就是天天4亿3千两百万。而现实,数据量会比这个大5%阁下。(现实上大部门是信息垃圾,可以通过数据压缩举办处理赏罚的,可是别人就是要搞你,能咋办)

上面是项目要求的指标,我想许多有不少大数据处理赏罚履历的同窗城市呲之以鼻,就这么点?嗯,我也看了许多大数据处理赏罚的对象,可是之前没处理赏罚过,看别人是头头是道,什么漫衍式,什么读写疏散,看起来确实很轻易办理。可是,题目没这么简朴,上面我说了,这是一个很是恶劣的项目,是一个行业恶性竞争典范的项目。

没有更多的处事器,而是这个处事器除了搭配数据库、齐集收罗器(就是数据理会、告警、存储的措施),还要支持30w点的北向接口(SNMP),在措施没有优化之前CPU常年占用80%以上。由于项目要求要行使双机热备,为了省事,镌汰不须要的贫困,我们把相干的处事放在一路,以便可以或许充实操作HA的特征(外部购置的HA体系)

体系数据正确性要求极其失常,要求从底层收罗体系到最上层的监控体系,一条数据都不能差

我们的体系架构如下,可以看到,个中数据库压力很是之大,尤其在LevelA节点:

SQLServer 数据库优化

硬件设置如下:

CPU:英特尔® 至强® 处理赏罚器 E5-2609 (4核, 2.40GHz, 10MB, 6.4 GT/s)

内存:4GB (2x2GB) DDR3 RDIMM Memory, 1333MHz,ECC

硬盘:500GB 7200 RPM 3.5'' SATA3 硬盘,Raid5.

数据库版本

回收的是SQLServer2012尺度版,HP提供的正版软件,穷乏许多企业版的NB成果。

写入瓶颈

起首碰着的第一个拦路虎就是,我们发明现有的措施下,SQLServer基础处理赏罚不了这么多的数据量,详细环境是奈何的呢?

我们的存储布局

一样平常为了存储大量的汗青数据,我们城市举办一个物理的分表,不然天天上百万条的记录,一年下来就是几亿条。因此,原本我们的表布局是这样的:

CREATE TABLE [dbo].[His20140822]( [No] [bigint] IDENTITY(1,1) NOT NULL, [Dtime] [datetime] NOT NULL, [MgrObjId] [varchar](36) NOT NULL, [Id] [varchar](50) NOT NULL, [Value] [varchar](50) NOT NULL, CONSTRAINT [PK_His20140822] PRIMARY KEY CLUSTERED ( [No] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]

No作为独一的标识、收罗装备Id(Guid)、监控指标Id(varchar(50))、记录时刻、记录值。并以收罗装备Id和监控指标Id作为索引,以便快速查找。

批量写入

写入其时是用BulKCopy,没错,就是它,号称写入百万笔记录都是秒级的

public static int BatchInert(string connectionString, string desTable, DataTable dt, int batchSize = 500) { using (var sbc = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction) { BulkCopyTimeout = 300, NotifyAfter = dt.Rows.Count, BatchSize = batchSize, DestinationTableName = desTable }) { foreach (DataColumn column in dt.Columns) sbc.ColumnMappings.Add(column.ColumnName, column.ColumnName); sbc.WriteToServer(dt); } return dt.Rows.Count; }

存在什么题目?

上面的架构,在天天4万万的数据都是OK的。可是,调解为上述配景下的设置时,齐集监控措施就内存溢出了,说明得知,吸取的太大都据,放在了内存中,可是没有来得及写入到数据库中,最终导致了天生的数据大于斲丧的数据,导致内存溢出,措施无法事变。

瓶颈到底在那边?

是由于RAID磁盘的题目?是数据布局的题目?是硬件的题目?是SQLServer版本的题目?是没有分区表的题目?照旧措施的题目?

其时时刻只有一个礼拜,一个礼拜搞欠好,项目禁锢就要我们滚开了,于是,有了持续事变48小时的壮举,有了处处打电话求人的抓鸡……

可是,这个时辰必要的是沉着,再沉着……SQLServer版本?硬件?今朝都不大也许换的。RAID磁盘阵列,应该不是。那么到底是什么,真TM的沉着不下来。

各人也许领会不到现场那种求助的空气,着实过了这么久,我本身也都很难再回到那种情境。可是可以这么说,或者我们此刻有了各类要领,可能处于局外人我们有更多思索,可是当一个项目压制你快到放弃的时辰,你当时的设法、思量在现场情形身分的制约下,都也许呈现重大的毛病。有也许让你快速的思索,也有也许思想停滞。有些同事在这种高压的情形下,乃至呈现了更多的初级错误,思想已经完全乱了,服从更低了……36小时没有合眼,可能只在工地上(下雨天处处都是泥巴,干了的话到时都是泥灰)眯两三个小时,然后继承干,持续这么一个礼拜!可能还要继承!

许多人给了许多设法,可是仿佛有效,又仿佛没用。等等,为什么是“仿佛有效,又仿佛没用”?我隐约约约中,仿佛抓住了一丝偏向,到底是什么?对了,验证,我们此刻是跑在现场情形下,之前没有题目,不代示意在的压力下没有题目,要在一个大型体系中说明这么个小成果,影响太大了,我们应该解析它。是的,是“单位测试”,就是单个要领的测试,我们必要验证每个函数,每个独立的步调到底耗时在那边?

慢慢测试验证体系瓶颈

修改BulkCopy的参数

阅读延展

1
3