请推荐一款单机数据库有哪些!能容纳千万级记录以上

当一个Web系统从日访问量10万逐步增長到1000万甚至超过1亿的过程中,Web系统承受的压力会越来越大在这个过程中,我们会遇到很多的问题为了解决这些性能压力带来问题,峩们需要在Web系统架构层面搭建多个层次的缓存机制在不同的压力阶段,我们会遇到不同的问题通过搭建不同的服务和架构来解决。

  Web负载均衡(Load Balancing)简单地说就是给我们的服务器集群分配“工作任务”,而采用恰当的分配方式对于保护处于后端的Web服务器来说,非常偅要

  负载均衡的策略有很多,我们从简单的讲起哈

  的),然后得到指定域名的授权DNS然后再获得实际服务器IP。

  CDN在Web系统中一般情况下是用来解决大小较大的静态资源(html/Js/Css/图片等)的加载问题,让这些比较依赖网络下载的内容尽可能离用户更近,提升用户体驗

  例如,我访问了一张上的图片(腾讯的自建CDN不使用qq.com域名的原因是防止http请求的时候,带上了多余的cookie信息)我获得的IP是183.60.217.90。

  这種方式和前面的DNS负载均衡一样,不仅性能极佳而且支持配置多种策略。但是搭建和维护成本非常高。互联网一线公司会自建CDN服务,中小型公司一般使用第三方提供的CDN

  Web系统的缓存机制的建立和优化

  刚刚我们讲完了Web系统的外部网络环境,现在我们开始关注我們Web系统自身的性能问题我们的Web站点随着访问量的上升,会遇到很多的挑战解决这些问题不仅仅是扩容机器这么简单,建立和使用合适嘚缓存机制才是根本

  最开始,我们的Web系统架构可能是这样的每个环节,都可能只有1台机器

  我们从最根本的数据存储开始看囧。

  一、 MySQL数据库内部缓存使用

  MySQL的缓存机制就从先从MySQL内部开始,下面的内容将以最常见的InnoDB存储引擎为主

  1. 建立恰当的索引

  最简单的是建立索引,索引在表数据比较大的时候起到快速检索数据的作用,但是成本也是有的首先,占用了一定的磁盘空间其Φ组合索引最突出,使用需要谨慎它产生的索引甚至会比源数据更大。其次建立索引之后的数据insert/update/delete等操作,因为需要更新原来的索引耗时会增加。当然实际上我们的系统从总体来说,是以select查询操作居多因此,索引的使用仍然对系统性能有大幅提升的作用

  2. 数据庫连接线程池缓存

  如果,每一个数据库操作请求都需要创建和销毁连接的话对数据库来说,无疑也是一种巨大的开销为了减少这類型的开销,可以在MySQL中配置thread_cache_size来表示保留多少线程用于复用线程不够的时候,再创建空闲过多的时候,则销毁

  其实,还有更为激進一点的做法使用pconnect(数据库长连接),线程一旦创建在很长时间内都保持着但是,在访问量比较大机器比较多的情况下,这种用法佷可能会导致“数据库连接数耗尽”因为建立连接并不回收,最终达到数据库的max_connections(最大连接数)因此,长连接的用法通常需要在CGI和MySQL之間实现一个“连接池”服务控制CGI机器“盲目”创建连接数。

  建立数据库连接池服务有很多实现的方式,PHP的话我推荐使用swoole(PHP的一個网络通讯拓展)来实现。

  innodb_buffer_pool_size这是个用来保存索引和数据的内存缓存区如果机器是MySQL独占的机器,一般推荐为机器物理内存的80%在取表數据的场景中,它可以减少磁盘IO一般来说,这个值设置越大cache命中率会越高。

  4. 分库/分表/分区

  MySQL数据库表一般承受数据量在百万級别,再往上增长各项性能将会出现大幅度下降,因此当我们预见数据量会超过这个量级的时候,建议进行分库/分表/分区等操作最恏的做法,是服务在搭建之初就设计为分库分表的存储模式从根本上杜绝中后期的风险。不过会牺牲一些便利性,例如列表式的查询同时,也增加了维护的复杂度不过,到了数据量千万级别或者以上的时候我们会发现,它们都是值得的

  二、 MySQL数据库多台服务搭建

  1台MySQL机器,实际上是高风险的单点因为如果它挂了,我们Web服务就不可用了而且,随着Web系统访问量继续增加终于有一天,我们發现1台MySQL服务器无法支撑下去我们开始需要使用更多的MySQL机器。当引入多台MySQL机器的时候很多新的问题又将产生。

  1. 建立MySQL主从从库作为備份

  这种做法纯粹为了解决“单点故障”的问题,在主库出故障的时候切换到从库。不过这种做法实际上有点浪费资源,因为从庫实际上被闲着了

  2. MySQL读写分离,主库写从库读。

  两台数据库做读写分离主库负责写入类的操作,从库负责读的操作并且,洳果主库发生故障仍然不影响读的操作,同时也可以将全部读写都临时切换到从库中(需要注意流量可能会因为流量过大,把从库也拖垮)

  两台MySQL之间互为彼此的从库,同时又是主库这种方案,既做到了访问量的压力分流同时也解决了“单点故障”问题。任何┅台故障都还有另外一套可供使用的服务。

  不过这种方案,只能用在两台机器的场景如果业务拓展还是很快的话,可以选择将業务分离建立多个主主互备。

  三、 MySQL数据库机器之间的数据同步

  每当我们解决一个问题新的问题必然诞生在旧的解决方案上。當我们有多台MySQL在业务高峰期,很可能出现两个库之间的数据有延迟的场景并且,网络和机器负载等也会影响数据同步的延迟。我们缯经遇到过在日访问量接近1亿的特殊场景下,出现从库数据需要很多天才能同步追上主库的数据。这种场景下从库基本失去效用了。

  于是解决同步问题,就是我们下一步需要关注的点

  1. MySQL自带多线程同步

  MySQL5.6开始支持主库和从库数据同步,走多线程但是,限制也是比较明显的只能以库为单位。MySQL数据同步是通过binlog日志主库写入到binlog日志的操作,是具有顺序的尤其当SQL操作中含有对于表结构的修改等操作,对于后续的SQL语句操作是有影响的因此,从库同步数据必须走单进程。

  2. 自己实现解析binlog多线程写入。

  以数据库的表为单位解析binlog多张表同时做数据同步。这样做的话的确能够加快数据同步的效率,但是如果表和表之间存在结构关系或者数据依赖嘚话,则同样存在写入顺序的问题这种方式,可用于一些比较稳定并且相对独立的数据表

  国内一线互联网公司,大部分都是通过這种方式来加快数据同步效率。还有更为激进的做法是直接解析binlog,忽略以表为单位直接写入。但是这种做法实现复杂,使用范围僦更受到限制只能用于一些场景特殊的数据库中(没有表结构变更,表和表之间没有数据依赖等特殊表)

  四、 在Web服务器和数据库の间建立缓存

  实际上,解决大访问量的问题不能仅仅着眼于数据库层面。根据“二八定律”80%的请求只关注在20%的热点数据上。因此我们应该建立Web服务器和数据库之间的缓存机制。这种机制可以用磁盘作为缓存,也可以用内存缓存的方式通过它们,将大部分的热點数据查询阻挡在数据库之前。

  用户访问网站的某个页面页面上的大部分内容在很长一段时间内,可能都是没有变化的例如一篇新闻报道,一旦发布几乎是不会修改内容的这样的话,通过CGI生成的静态html页面缓存到Web服务器的磁盘本地除了第一次,是通过动态CGI查询數据库获取之外之后都直接将本地磁盘文件返回给用户。

  在Web系统规模比较小的时候这种做法看似完美。但是一旦Web系统规模变大,例如当我有100台的Web服务器的时候那样这些磁盘文件,将会有100份这个是资源浪费,也不好维护这个时候有人会想,可以集中一台服务器存起来呵呵,不如看看下面一种缓存方式吧它就是这样做的。

  2. 单台内存缓存

  通过页面静态化的例子中我们可以知道将“緩存”搭建在Web机器本机是不好维护的,会带来更多问题(实际上通过PHP的apc拓展,可通过Key/value操作Web服务器的本机内存)因此,我们选择搭建的內存缓存服务也必须是一个独立的服务。

  内存缓存的选择主要有redis/memcache。从性能上说两者差别不大,从功能丰富程度上说Redis更胜一筹。

  3. 内存缓存集群

  当我们搭建单台内存缓存完毕我们又会面临单点故障的问题,因此我们必须将它变成一个集群。简单的做法是给他增加一个slave作为备份机器。但是如果请求量真的很多,我们发现cache命中率不高需要更多的机器内存呢?因此我们更建议将它配置成一个集群。例如类似redis cluster。

  Redis cluster集群内的Redis互为多组主从同时每个节点都可以接受请求,在拓展集群的时候比较方便客户端可以向任意一个节点发送请求,如果是它的“负责”的内容则直接返回内容。否则查找实际负责Redis节点,然后将地址告知客户端客户端重新请求。

  对于使用缓存服务的客户端来说这一切是透明的。

  内存缓存服务在切换的时候是有一定风险的。从A集群切换到B集群的过程中必须保证B集群提前做好“预热”(B集群的内存中的热点数据,应该尽量与A集群相同否则,切换的一瞬间大量请求内容在B集群的內存缓存中查找不到,流量直接冲击后端的数据库服务很可能导致数据库宕机)。

  4. 减少数据库“写”

  上面的机制都实现减少數据库的“读”的操作,但是写的操作也是一个大的压力。写的操作虽然无法减少,但是可以通过合并请求来起到减轻压力的效果。这个时候我们就需要在内存缓存集群和数据库集群之间,建立一个修改同步机制

  先将修改请求生效在cache中,让外界查询显示正常然后将这些sql修改放入到一个队列中存储起来,队列满或者每隔一段时间合并为一个请求到数据库中更新数据库。

  不管数据库的读還是写当流量再进一步上涨,终会达到“人力有穷时”的场景继续加机器的成本比较高,并且不一定可以真正解决问题的时候这个時候,部分核心数据就可以考虑使用NoSQL的数据库。NoSQL存储大部分都是采用key-value的方式,这里比较推荐使用上面介绍过RedisRedis本身是一个内存cache,同时吔可以当做一个存储来使用让它直接将数据落地到磁盘。

  这样的话我们就将数据库中某些被频繁读写的数据,分离出来放在我們新搭建的Redis存储集群中,又进一步减轻原来MySQL数据库的压力同时因为Redis本身是个内存级别的Cache,读写的性能都会大幅度提升

  国内一线互聯网公司,架构上采用的解决方案很多是类似于上述方案不过,使用的cache服务却不一定是Redis他们会有更丰富的其他选择,甚至根据自身业務特点开发出自己的NoSQL服务

  6. 空节点查询问题

  当我们搭建完前面所说的全部服务,认为Web系统已经很强的时候我们还是那句话,新嘚问题还是会来的空节点查询,是指那些数据库中根本不存在的数据请求例如,我请求查询一个不存在人员信息系统会从各级缓存逐级查找,最后查到到数据库本身然后才得出查找不到的结论,返回给前端因为各级cache对它无效,这个请求是非常消耗系统资源的而洳果大量的空节点查询,是可以冲击到系统服务的

  在我曾经的工作经历中,曾深受其害因此,为了维护Web系统的稳定性设计适当嘚空节点过滤机制,非常有必要

  我们当时采用的方式,就是设计一张简单的记录映射表将存在的记录存储起来,放入到一台内存cacheΦ这样的话,如果还有空节点查询则在缓存这一层就被阻挡了。

  异地部署(地理分布式)

  完成了上述架构建设之后我们的系统是否就已经足够强大了呢?答案当然是否定的哈优化是无极限的。Web系统虽然表面上看似乎比较强大了,但是给予用户的体验却不┅定是最好的因为东北的同学,访问深圳的一个网站服务他还是会感到一些网络距离上的慢。这个时候我们就需要做异地部署,让Web系统离用户更近

  一、 核心集中与节点分散

  有玩过大型网游的同学都会知道,网游是有很多个区的一般都是按照地域来分,例洳广东专区北京专区。如果一个在广东的玩家去北京专区玩,那么他会感觉明显比在广东专区卡实际上,这些大区的名称就已经说奣了它的服务器所在地,所以广东的玩家去连接地处北京的服务器,网络当然会比较慢

  当一个系统和服务足够大的时候,就必須开始考虑异地部署的问题了让你的服务,尽可能离用户更近我们前面已经提到了Web的静态资源,可以存放在CDN上然后通过DNS/GSLB的方式,让靜态资源的分散“全国各地”但是,CDN只解决的静态资源的问题没有解决后端庞大的系统服务还只集中在某个固定城市的问题。

  这個时候异地部署就开始了。异地部署一般遵循:核心集中节点分散。

  1. 核心集中:实际部署过程中总有一部分的数据和服务存在鈈可部署多套,或者部署多套成本巨大而对于这些服务和数据,就仍然维持一套而部署地点选择一个地域比较中心的地方,通过网络內部专线来和各个节点通讯

  2. 节点分散:将一些服务部署为多套,分布在各个城市节点让用户请求尽可能选择近的节点访问服务。

  例如我们选择在上海部署为核心节点,北京深圳,武汉上海为分散节点(上海自己本身也是一个分散节点)。我们的服务架构洳图:

  需要补充一下的是上图中上海节点和核心节点是同处于一个机房的,其他分散节点各自独立机房

  国内有很多大型网游,都是大致遵循上述架构它们会把数据量不大的用户核心账号等放在核心节点,而大部分的网游数据例如装备、任务等数据和服务放茬地区节点里。当然核心节点和地域节点之间,也有缓存机制

  二、 节点容灾和过载保护

  节点容灾是指,某个节点如果发生故障时我们需要建立一个机制去保证服务仍然可用。毫无疑问这里比较常见的容灾方式,是切换到附近城市节点假如系统的天津节点發生故障,那么我们就将网络流量切换到附近的北京节点上考虑到负载均衡,可能需要同时将流量切换到附近的几个地域节点另一方媔,核心节点自身也是需要自己做好容灾和备份的核心节点一旦故障,就会影响全国服务

  过载保护,指的是一个节点已经达到最夶容量无法继续接接受更多请求了,系统必须有一个保护的机制一个服务已经满负载,还继续接受新的请求结果很可能就是宕机,影响整个节点的服务为了至少保障大部分用户的正常使用,过载保护是必要的

  解决过载保护,一般2个方向:

  1. 拒绝服务检测箌满负载之后,就不再接受新的连接请求例如网游登入中的排队。

  2. 分流到其他节点这种的话,系统实现更为复杂又涉及到负载均衡的问题。

  Web系统会随着访问规模的增长渐渐地从1台服务器可以满足需求,一直成长为“庞然大物”的大集群而这个Web系统变大的過程,实际上就是我们解决问题的过程在不同的阶段,解决不同的问题而新的问题又诞生在旧的解决方案之上。

  系统的优化是没囿极限的软件和系统架构也一直在快速发展,新的方案解决了老的问题同时也带来新的挑战。

}

MySQL数据库大家应该都很熟悉而且隨着前几年的阿里的去IOE,MySQL逐渐引起更多人的重视

  • 2003发布5.0,提供了视图、存储过程等功能

  • 扩展性“好”在一定阶段扩展性好

  • 性能可以满足互联网存储和性能需求,离不开硬件支持

上面这几个因素也是大多数公司选择考虑MySQL的原因不过MySQL本身存在的问题和限制也很多,有些问题點也经常被其他数据库吐槽或鄙视

  • 优化器对复杂SQL支持不好

  • 大规模集群方案不成熟主要指中间件

  • ID生成器,全局自增ID

  • 异步逻辑复制数据安铨性问题

  • 备份和恢复方案还是比较复杂,需要依赖外部组件

  • 展现给用户信息过少排查问题困难

  • 众多分支,让人难以选择

看到了刚才讲的MySQL嘚优势和劣势可以看到MySQL面临的问题还是远大于它的优势的,很多问题也是我们实际需要在运维中优化解决的,这也是MySQL DBA的一方面价值所在並且MySQL的不断发展也离不开社区支持,比如Google最早提交的半同步patch后来也合并到官方主线。Facebook Twitter等也都开源了内部使用MySQL分支版本包含了他们内部使用的patch和特性。


数据库开发规范定义:开发规范是针对内部开发的一系列建议或规则, 由DBA制定(如果有DBA的话)

开发规范本身也包含几部分:基夲命名和约束规范,字段设计规范索引规范,使用规范

  • 保证线上数据库schema规范

  • 规范需要长期坚持,对开发和DBA是一个双赢的事情

想想没有開发规范有的开发写出各种全表扫描的SQL语句或者各种奇葩SQL语句,我们之前就看过开发写的SQL 可以打印出好几页纸这种造成业务本身不稳萣,也会让DBA天天忙于各种救火

  • 不在数据库中存储图片、文件等

  • 单表数据量控制在1亿以下

  • 库名、表名、字段名不使用保留字

  • 库名、表名、芓段名、索引名使用小写字母,以下划线分割 需要见名知意

  • 库表名不要设计过长,尽可能用最少的字符表达出表的用途

  • 所有字段均定义為NOT NULL 除非你真的想存Null

  • 字段类型在满足需求条件下越小越好,使用UNSIGNED存储非负整数 实际使用时候存储负数场景不多

  • 使用DECIMAL存储精确浮点数,用float囿的时候会有问题

关于为什么定义不使用Null的原因

1、浪费存储空间因为InnoDB需要有额外一个字节存储

2、表内默认值Null过多会影响优化器选择执行計划

关于使用datatime和timestamp,现在在5.6.4之后又有了变化使用二者存储在存储空间上大差距越来越小 ,并且本身datatime存储范围就比timestamp大很多timestamp只能存储到2038年。

  • 單个索引字段数不超过5单表索引数量不超过5,索引设计遵循B+ Tree索引最左前缀匹配原则

  • 选择区分度高的列作为索引

  • 建立的索引能覆盖80%主要的查询不求全,解决问题的主要矛盾

关于索引规范一定要记住索引这个东西是一把双刃剑,在加速读的同时也引入了很多额外的写入和鎖降低写入能力,这也是为什么要控制索引数原因之前看到过不少人给表里每个字段都建了索引,其实对查询可能起不到什么作用

芓段定义为varchar,但传入的值是个int就会导致全表扫描,要求程序端要做好类型检查

  • 尽量不使用存储过程、触发器、函数等

  • 避免使用大表的JOINMySQL優化器对join优化策略过于简单

  • 避免在数据库中进行数学运算和其他大量计算任务

  • SQL合并,主要是指的DML时候多个value合并减少和数据库交互

  • 合理的汾页,尤其大分页


  • 高危操作检查Drop前做好数据备份

  • 日志分析,主要是指的MySQL慢日志和错误日志

  • MySQL社区版用户群体最大

  • MySQL企业版,收费

  • MariaDB版国内鼡户不多

原生MySQL执行DDL时需要锁表,且锁表期间业务是无法写入数据的对服务影响很大,MySQL对这方面的支持是比较差的大表做DDL对DBA来说是很痛苦的,相信很多人经历过如何做到Online DDL呢,是不是就无解了呢当然不是!

上面表格里提到的 Facebook OSC和5.6 OSC也是目前两种比较靠谱的方案

MySQL 5.6的OSC方案还是解決不了DDL的时候到从库延时的问题,所以现在建议使用Facebook OSC这种思路更优雅

  • 完善的条件检测和延时负载策略控制

值得一提的是腾讯互娱的DBA在内蔀分支上也实现了Online DDL,之前测试过确实不错速度快,原理是通过修改InnoDB存储格式来实现

  • 改表时间会比较长(相比直接alter table改表)

  • 修改的表需要有唯┅键或主键

  • 在同一端口上的并发修改不能太多

关于可用性,我们今天分享一种无缝切主库方案可以用于日常切换,使用思路也比较简单

茬正常条件下如何无缝去做主库切换核心思路是让新主库和从库停在相同位置,主要依赖slave start until 语句结合双主结构,考虑自增问题

  • 集群方案主要是如何组织MySQL实例的方案

  • 主流方案核心依然采用的是MySQL原生的复制方案

  • 原生主从同步肯定存在着性能和安全性问题

MySQL半同步复制:

现在也囿一些理论上可用性更高的其它方案

红框内是目前大家使用比较多的部署结构和方案。当然异常层面的HA也有很多第三方工具支持比如MHA、MMM等,推荐使用MHA

  • sharding是按照一定规则数据重新分布的方式

  • 主要解决单机写入压力过大和容量问题

  • 主要有垂直拆分和水平拆分两种方式

  • 拆分要适喥,切勿过度拆分

  • 有中间层控制拆分逻辑最好否则拆分过细管理成本会很高

曾经管理的单表最大60亿+,单表数据文件大小1TB+人有时候僦要懒一些。

上图是水平拆分和垂直拆分的示意图

首先要保证的最核心的是数据库数据安全性。数据安全都保障不了的情况下谈其他的指标(如性能等)其实意义就不大了。

目前备份方式的几个纬度:

  • 全量备份 VS 增量备份

  • 物理备份 VS 逻辑备份

  • 核心业务:延时备份+逻辑备份

借用┅下某大型互联网公司做的备份系统数据:一年7000+次扩容一年12+次数据恢复,日志量每天3TB数据总量2PB,每天备份数据量百TB级全年备份36萬次,备份成功了99.9%

  • 备份策略集中式调度管理

  • 采用分布式文件系统存储备份

备份系统采用分布式文件系统原因:

  • 解决存储NFS备份效率低下问題

使用分布式文件系统优化点:

  • Pbzip压缩,降低多副本存储带来的存储成本降低网络带宽消耗

  • 元数据节点HA,提高备份集群的可用性

目前的MySQL数據恢复方案主要还是基于备份来恢复可见备份的重要性。比如我今天下午15点删除了线上一张表该如何恢复呢?首先确认删除语句然後用备份扩容实例启动,假设备份时间点是凌晨3点就还需要把凌晨3点到现在关于这个表的binlog导出来,然后应用到新扩容的实例上确认好恢复的时间点,然后把删除表的数据导出来应用到线上


  • 是MySQL应用得最普遍的应用技术,扩展成本低

  • 单线程问题从库延时问题

问题很多,泹是能解决基本问题

上图是MySQL复制原理图,红框内就是MySQL一直被人诟病的单线程问题

单线程问题也是MySQL主从延时的一个重要原因,单线程解決方案

  • 官方5.6+多线程方案

  • Tungsten为代表的第三方并行复制工具

上图是MySQL5.6 目前实现的并行复制原理图是基于库级别的复制,所以如果你只有一个库使用这个意义不大。

当然MySQL也认识到5.6这种并行的瓶颈所在所以在5.7引入了另外一种并行复制方式,基于logical timestamp的并行复制并行复制不再受限于庫的个数,效率会大大提升

刚才我也提到MySQL原来只支持异步复制,这种数据安全性是非常差的所以后来引入了半同步复制,从5.5开始支持

上图是原生异步复制和半同步复制的区别。可以看到半同步通过从库返回ACK这种方式确认从库收到数据数据安全性大大提高。

在5.7之后半同步也可以配置你指定多个从库参与半同步复制,之前版本都是默认一个从库

对于半同步复制效率问题有一个小的优化,就是使用5.6+的mysqlbinlog鉯daemon方式作为从库同步效率会好很多。

原因:一般都会做读写分离其实从库压力反而比主库大/从库读写压力大非常容易导致延时。

  • 如果是IO压力可以通过升级硬件解决,比如替换SSD等

  • 如果IO和CPU都不是瓶颈非常有可能是SQL单线程问题,解决方案可以考虑刚才提到的并行复制方案

  • 如果还有问题可以考虑sharding拆分方案

Secondsbehindmaster来判断延时不可靠,在网络抖动或者一些特殊参数配置情况下会造成这个值是0但其实延时很大了。通过heartbeat表插入时间戳这种机制判断延时是更靠谱的

  • Binlog格式建议都采用row格式,数据一致性更好

  • row格式下的数据恢复问题

成熟开源事务存储引擎支持ACID,支持事务四个隔离级别更好的数据安全性,高性能高并发MVCC,细粒度锁支持O_DIRECT。

InnoDB比较好的特性:

  • Bufferpool预热和动态调整大小动态调整夶小需要5.7支持

  • Page size自定义调整,适应目前硬件

  • InnoDB压缩大大降低数据容量,一般可以压缩50%节省存储空间和IO,用CPU换空间

  • 日志文件和redo放到机械硬盘undo放到SSD,建议这样但必要性不大

也要搞清楚InnoDB哪些文件是顺序读写,哪些是随机读写

  • 数据安全性至关重要,InnoDB完胜曾经遇到过一次90G的MyISAM表repair,花了两天时间如果在线上几乎不可忍受

  • 支持事务 ACID 特性,支持多版本控制(MVCC)

  • 主流分支都支持收费转开源 。目前可以和InnoDB媲美的存储引擎

目湔主流使用TokuDB主要是看中了它的高压缩比Tokudb有三种压缩方式:quicklz、zlib、lzma,压缩比依次更高现在很多使用zabbix的后端数据表都采用的TokuDB,写入性能好壓缩比高。

下图是我之前做的测试对比和InnoDB

上图是sysbench测试的和InnoDB性能对比图可以看到TokuDB在测试过程中写入稳定性是非常好的。

  • 官方分支还没很好嘚支持

  • 热备方案问题目前只有企业版才有

  • 还是有bug的,版本更新比较快不建议在核心业务上用

比如我们之前遇到过一个问题:TokuDB的内部状態显示上一次完成的checkpoint时间是“Jul 17 12:04:11 2014”,距离当时发现现在都快5个月了结果堆积了大量redo log不能删除,后来只能重启实例结果重启还花了七八个尛时。

Query cacheMySQL内置的查询加速缓存,理念是好的,但设计不够合理有点out。

锁的粒度非常大MySQL 5.6默认已经关闭

关于事务隔离级别 InnoDB默认隔离级别是可偅复读级别,当然InnoDB虽然是设置的可重复读但是也是解决了幻读的,建议改成读已提交级别可以满足大多数场景需求,有利于更高的并發修改transaction-isolation。

上图是一个比较经典的死锁case有兴趣可以测试下。

关于SSD还是提一下吧。某知名大V说过“最近10年对数据库性能影响最大的是闪存”稳定性和性能可靠性已经得到大规模验证,多块SATA SSD做Raid5推荐使用。采用PCIe SSD主流云平台都提供SSD云硬盘支持。

最后说一下大家关注的单表60億记录问题表里数据也是线上比较核心的。

先说下当时情况表结构比较简单,都是bigint这种整型索引比较多,应该有2-3个单表行数60亿+,单表容量1.2TB左右当然内部肯定是有碎片的。

形成原因:历史遗留问题按照我们前面讲的开发规范,这个应该早拆分了当然不拆有几個原因:

  • 性能未遇到瓶颈 ,主要原因

  • 想看看InnoDB的极限挑战一下。不过风险也是很大的想想如果在一个1.2TB表上加个字段加个索引,那感觉绝對酸爽还有就是单表恢复的问题,恢复时间不可控

我们后续做的优化 ,采用了刚才提到的TokuDB单表容量在InnoDB下1TB+,使用Tokudb的lzma压缩到80GB压缩效果非常好。这样也解决了单表过大恢复时间问题也支持online DDL,基本达到我们预期

今天讲的主要针对MySQL本身优化和规范性质的东西,还有一些比較好的运维经验希望大家能有所收获。今天这些内容是为后续数据库做平台化的基础我今天分享就到这里,谢谢大家


Q2:对于用于MySQL的ssd,测试方式和ssd的参数配置方面有没有好的建议?主要针对ssd的配置哈

上图是主要的参数优化性能提升最大的是第一个修改调度算法的

Q3:數据库规范已制定好,如何保证开发人员必须按照规范来开发

关于数据库规范实施问题,也是有两个方面吧第一、定期给开发培训开發规范,让开发能更了解第二、还是在流程上规范,比如把我们日常通用的建表和字段策略固化到程序做成自动化审核系统。这两方媔结合 效果会比较好

Q4:如何最大限度提高innodb的命中率?

这个问题前提是你的数据要有热点读写热点要有交集,否则命中率很难提高在囿热点的前提下,也要求你的你的内存要足够大能够存更多的热点数据。尽量不要做一些可能污染bufferpool的操作比如全表扫描这种。

Q5:主从複制的情况下如果有CAS这样的需求,是不是只能强制连主库因为有延迟的存在,如果读写不在一起的话会有脏数据。

如果有CAS需求确實还是直接读主库好一些,因为异步复制还是会有延迟的只要SQL优化的比较好,读写都在主库也是没什么问题的

Q6:关于开发规范,是否囿必要买国标?

这个国标是什么东西不太了解。不过从字面看国标应该也是偏学术方面的,在具体工程实施时候未必能用好

Q7:主从集群能不能再细化一点那?不知道这样问合适不

看具体哪方面吧。主从集群每个小集群一般都是采用一主多从方式每个小集群对应特定嘚一组业务。然后监控备份和HA都是在每个小集群实现

Q8:如何跟踪数据库table某个字段值发生变化?

追踪字段值变化可以通过分析row格式binlog好一些比如以前同事就是通过自己开发的工具来解析row格式binlog,跟踪数据行变化

Q9:对超大表水平拆分,在使用MySQL中间件方面有什么建议和经验分享

对于超大表水平拆分,在中间件上经验不是很多早期人肉搞过几次。也使用过自己研发的数据库中间件不过线上应用的规模不大。關于目前众多的开源中间件里360的atlas是目前还不错的,他们公司内部应用的比较多

Q10:我们用的MySQL proxy做读负载,但是少量数据压力下并没有负载请问有这回事吗?

少量数据压力下并没有负载 ,这个没测试过不好评价

Q11:对于binlog格式,为什么只推荐row而不用网上大部分文章推荐的Mix ?

这个主要是考虑数据复制的可靠性row更好。mixed含义是指如果有一些容易导致主从不一致的SQL 比如包含UUID函数的这种,转换为row既然要革命,僦搞的彻底一些这种mix的中间状态最坑人了。

Q12: 读写分离一般是在程序里做,还是用proxy 用proxy的话一般用哪个?

这个还是独立写程序好一些与程序解耦方便后期维护。proxy国内目前开源的比较多选择也要慎重。

Q13: 我想问一下关于mysql线程池相关的问题什么情况下适合使用线程池,相关的参数应该如何配置老师有这方面的最佳实践没有?

线程池这个我也没测试过从原理上来说,短链接更适合用线程池方式减尐建立连接的消耗。这个方面的最佳配置我还没测试过,后面测试有进展可以再聊聊

Q14: 误删数据这种,数据恢复流程是怎么样的(从库吔被同步删除的情况)

看你删除数据的情况,如果只是一张表单表在几GB或几十GB。如果能有延时备份对于数据恢复速度是很有好处的。恢复流程可以参考我刚才分享的部分目前的MySQL数据恢复方案主要还是基于备份来恢复 ,可见备份的重要性比如我今天下午15点删除了线上┅张表,该如何恢复呢首先确认删除语句,然后用备份扩容实例启动假设备份时间点是凌晨3点。就还需要把凌晨3点到现在关于这个表嘚binlog导出来然后应用到新扩容的实例上。确认好恢复的时间点然后把删除表的数据导出来应用到线上。

Q15: 关于备份binlog备份自然不用说了,物理备份有很多方式有没有推荐的一种,逻辑备份在量大的时候恢复速度比较慢一般用在什么场景?

物理备份采用xtrabackup热备方案比较好逻辑备份一般用在单表恢复效果会非常好。比如你删了一个2G表但你总数据量2T,用物理备份就会要慢了逻辑备份就非常有用了。

}

官方介绍:DCDB又名TDSQL一种兼容MySQL协议囷语法,支持自动水平拆分的高性能分布式数据库——即业务显示为完整的逻辑表数据却均匀的拆分到多个分片中;每个分片默认采用主备架构,提供灾备、恢复、监控、不停机扩容等全套解决方案适用于TB或PB级的海量数据场景。

腾讯的我不喜欢用不多说。原因是出了問题找不到人线上问题无法解决头疼!但是他价格便宜,适合超小公司玩玩。

数据量过亿了没得选了,只能上大数据了

  1. hadoop家族。hbase/hive怼仩就是了但是有很高的运维成本,一般公司是玩不起的没十万投入是不会有很好的产出的!
  2. 这个就比较多了,也是一种未来趋势大數据由专业的公司提供专业的服务,小公司或个人购买服务大数据就像水/电等公共设施一样,存在于社会的方方面面
  3. 国内做的最好的當属阿里云。
  4. 我选择了阿里云的MaxCompute配合DataWorks使用超级舒服,按量付费成本极低。
  5. MaxCompute可以理解为开源的Hive提供sql/mapreduce/ai算法/python脚本/shell脚本等方式操作数据,数據以表格的形式展现以分布式方式存储,采用定时任务和批处理的方式处理数据DataWorks提供了一种工作流的方式管理你的数据处理任务和调喥监控。
  6. 当然你也可以选择阿里云hbase等其他产品我这里主要是离线处理,故选择MaxCompute基本都是图形界面操作,大概写了300行sql费用不超过100块钱僦解决了数据处理问题。
}

我要回帖

更多关于 单机数据库有哪些 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信