mysql运维相关

1.为何要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不一样的分库分表中间件都有什么优势和缺点?
2.如今有一个未分库分表的系统,将来要分库分表,如何设计才可让系统从未分库分表动态切换到分库分表上
3.如何设计能够动态扩容缩容的分库分表方案?
4.分库分表以后,id主键如何处理?
5.mysql的主从同步与读写分离
(1)如何实现mysql的读写分离?
(2)MySQL主从复制原理的是啥?
(3)mysql主从同步延时问题
6.mysql何时建立索引
7.mysql索引底层数据结构与算法mysql

 

1.为何要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不一样的分库分表中间件都有什么优势和缺点?
大家具体是如何对数据库如何进行垂直拆分或水平拆分的?算法

实际上这是跟着你的公司业务发展走的,你公司业务发展越好,用户就越多,数据量越大,请求量越大,那你单个数据库必定扛不住。
好比你单表都几千万数据了,你肯定你能抗住么?绝对不行,单表数据量太大,会极大影响你的sql执行的性能,到了后面你的sql可能就跑的很慢了。通常来讲,就以个人经验来看,单表到几百万的时候,性能就会相对差一些了,你就得分表了。
分表是啥意思?就是把一个表的数据放到多个表中,而后查询的时候你就查一个表。好比按照用户id来分表,将一个用户的数据就放在一个表中。而后操做的时候你对一个用户就操做那个表就行了。这样能够控制每一个表的数据量在可控的范围内,好比每一个表就固定在200万之内。
分库是啥意思?就是你一个库通常咱们经验而言,最多支撑到并发2000,必定要扩容了,并且一个健康的单库并发值你最好保持在每秒1000左右,不要太大。那么你能够将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。sql


sharding-jdbc这种client层方案的优势在于不用部署,运维成本低,不须要代理层的二次转发请求,性能很高,可是若是遇到升级啥的须要各个系统都从新升级版本再发布,各个系统都须要耦合sharding-jdbc的依赖;
mycat这种proxy层方案的缺点在于须要部署,本身及运维一套中间件,运维成本高,可是好处在于对于各个项目是透明的,若是遇到升级之类的都是本身中间件那里搞就好了。
一般来讲,这两个方案其实均可以选用,可是我我的建议中小型公司选用sharding-jdbc,client层方案轻便,并且维护成本低,不须要额外增派人手,并且中小型公司系统复杂度会低一些,项目也没那么多;
可是中大型公司最好仍是选用mycat这类proxy层方案,由于可能大公司系统和项目很是多,团队很大,人员充足,那么最好是专门弄我的来研究和维护mycat,而后大量项目直接透明使用便可。数据库

如何对数据库如何进行垂直拆分或水平拆分的?
水平拆分的意思,就是把一个表的数据给弄到多个库的多个表里去,可是每一个库的表结构都同样,只不过每一个库表放的数据是不一样的,全部库表的数据加起来就是所有数据。水平拆分的意义,就是将数据均匀放更多的库里,而后用多个库来抗更高的并发,还有就是用多个库的存储容量来进行扩容。
垂直拆分的意思,就是把一个有不少字段的表给拆分红多个表,或者是多个库上去。每一个库表的结构都不同,每一个库表都包含部分字段。通常来讲,会将较少的访问频率很高的字段放到一个表里去,而后将较多的访问频率很低的字段放到另一个表里去。由于数据库是有缓存的,你访问频率高的行字段越少,就能够在缓存里缓存更多的行,性能就越好。这个通常在表层面作的较多一些。
这个其实挺常见的,不必定我说,你们不少同窗可能本身都作过,把一个大表拆开,订单表、订单支付表、订单商品表。
还有表层面的拆分,就是分表,将一个表变成N个表,就是让每一个表的数据量控制在必定范围内,保证SQL的性能。不然单表数据量越大,SQL性能就越差。通常是200万行左右,不要太多,可是也得看具体你怎么操做,也多是500万,或者是100万。你的SQL越复杂,就最好让单表行数越少。
好了,不管是分库了仍是分表了,上面说的那些数据库中间件都是能够支持的。就是基本上那些中间件能够作到你分库分表以后,中间件能够根据你指定的某个字段值,好比说userid,自动路由到对应的库上去,而后再自动路由到对应的表里去。
你就得考虑一下,你的项目里该如何分库分表?通常来讲,垂直拆分,你能够在表层面来作,对一些字段特别多的表作一下拆分;水平拆分,你能够说是并发承载不了,或者是数据量太大,容量承载不了,你给拆了,按什么字段来拆,你本身想好;分表,你考虑一下,你若是哪怕是拆到每一个库里去,并发和容量都ok了,可是每一个库的表仍是太大了,那么你就分表,将这个表分开,保证每一个表的数据量并非很大。
并且这儿还有两种分库分表的方式,一种是按照range来分,就是每一个库一段连续的数据,这个通常是按好比时间范围来的,可是这种通常较少用,由于很容易产生热点问题,大量的流量都打在最新的数据上了;或者是按照某个字段hash一下均匀分散,这个较为经常使用。
range来分,好处在于说,后面扩容的时候,就很容易,由于你只要预备好,给每月都准备一个库就能够了,到了一个新的月份的时候,天然而然,就会写新的库了;缺点,可是大部分的请求,都是访问最新的数据。实际生产用range,要看场景,你的用户不是仅仅访问最新的数据,而是均匀的访问如今的数据以及历史的数据
hash分法,好处在于说,能够平均分配没给库的数据量和请求压力;坏处在于说扩容起来比较麻烦,会有一个数据迁移的这么一个过程缓存


2.如今有一个未分库分表的系统,将来要分库分表,如何设计才可让系统从未分库分表动态切换到分库分表上
双写迁移方案
这个是咱们经常使用的一种迁移方案,比较靠谱一些,不用停机,不用看北京凌晨4点的风景
简单来讲,就是在线上系统里面,以前全部写库的地方,增删改操做,都除了对老库增删改,都加上对新库的增删改,这就是所谓双写,同时写俩库,老库和新库。
而后系统部署以后,新库数据差太远,用以前说的导数工具,跑起来读老库数据写新库,写的时候要根据gmt_modified这类字段判断这条数据最后修改的时间,除非是读出来的数据在新库里没有,或者是比新库的数据新才会写。
接着导完一轮以后,有可能数据仍是存在不一致,那么就程序自动作一轮校验,比对新老库每一个表的每条数据,接着若是有不同的,就针对那些不同的,从老库读数据再次写。反复循环,直到两个库每一个表的数据都彻底一致为止。
接着当数据彻底一致了,就ok了,基于仅仅使用分库分表的最新代码,从新部署一次,不就仅仅基于分库分表在操做了么,尚未几个小时的停机时间,很稳。因此如今基本玩儿数据迁移之类的,都是这么干了。服务器


3.如何设计能够动态扩容缩容的分库分表方案?
(1)选择一个数据库中间件,调研、学习、测试
(2)设计你的分库分表的一个方案,你要分红多少个库,每一个库分红多少个表,3个库每一个库4个表
(3)基于选择好的数据库中间件,以及在测试环境创建好的分库分表的环境,而后测试一下可否正常进行分库分表的读写
(4)完成单库单表到分库分表的迁移,双写方案
(5)线上系统开始基于分库分表对外提供服务
(6)扩容了,扩容成6个库,每一个库须要12个表,你怎么来增长更多库和表呢?数据结构


一开始上来就是32个库,每一个库32个表,1024张表
我能够告诉各位同窗说,这个分法,第一,基本上国内的互联网确定都是够用了,第二,不管是并发支撑仍是数据量支撑都没问题
每一个库正常承载的写入并发量是1000,那么32个库就能够承载32 * 1000 = 32000的写并发,若是每一个库承载1500的写并发,32 * 1500 = 48000的写并发,接近5万/s的写入并发,前面再加一个MQ,削峰,每秒写入MQ 8万条数据,每秒消费5万条数据。
有些除非是国内排名很是靠前的这些公司,他们的最核心的系统的数据库,可能会出现几百台数据库的这么一个规模,128个库,256个库,512个库
1024张表,假设每一个表放500万数据,在MySQL里能够放50亿条数据
每秒的5万写并发,总共50亿条数据,对于国内大部分的互联网公司来讲,其实通常来讲都够了
谈分库分表的扩容,第一次分库分表,就一次性给他分个够,32个库,1024张表,可能对大部分的中小型互联网公司来讲,已经能够支撑好几年了
一个实践是利用32 * 32来分库分表,即分为32个库,每一个库里一个表分为32张表。一共就是1024张表。根据某个id先根据32取模路由到库,再根据32取模路由到库里的表。
刚开始的时候,这个库可能就是逻辑库,建在一个数据库上的,就是一个mysql服务器可能建了n个库,好比16个库。后面若是要拆分,就是不断在库和mysql服务器之间作迁移就能够了。而后系统配合改一下配置便可。
好比说最多能够扩展到32个数据库服务器,每一个数据库服务器是一个库。若是仍是不够?最多能够扩展到1024个数据库服务器,每一个数据库服务器上面一个库一个表。由于最可能是1024个表么。
这么搞,是不用本身写代码作数据迁移的,都交给dba来搞好了,可是dba确实是须要作一些库表迁移的工做,可是总比你本身写代码,抽数据导数据来的效率高得多了。
哪怕是要减小库的数量,也很简单,其实说白了就是按倍数缩容就能够了,而后修改一下路由规则。
对2 ^ n取模
orderId 模 32 = 库
orderId / 32 模 32 = 表
259 3 8
1189 5 5
352 0 11
4593 17 15架构

一、设定好几台数据库服务器,每台服务器上几个库,每一个库多少个表,推荐是32库 * 32表,对于大部分公司来讲,可能几年都够了
二、路由的规则,orderId 模 32 = 库,orderId / 32 模 32 = 表
三、扩容的时候,申请增长更多的数据库服务器,装好mysql,倍数扩容,4台服务器,扩到8台服务器,16台服务器
四、由dba负责将原先数据库服务器的库,迁移到新的数据库服务器上去,不少工具,库迁移,比较便捷
五、咱们这边就是修改一下配置,调整迁移的库所在数据库服务器的地址
六、从新发布系统,上线,原先的路由规则变都不用变,直接能够基于2倍的数据库服务器的资源,继续进行线上系统的提供服务并发


4.分库分表以后,id主键如何处理?
snowflake算法
twitter开源的分布式id生成算法,就是把一个64位的long型的id,1个bit是不用的,用其中的41 bit做为毫秒数,用10 bit做为工做机器id,12 bit做为序列号
1 bit:不用,为啥呢?由于二进制里第一个bit为若是是1,那么都是负数,可是咱们生成的id都是正数,因此第一个bit统一都是0
41 bit:表示的是时间戳,单位是毫秒。41 bit能够表示的数字多达2^41 - 1,也就是能够标识2 ^ 41 - 1个毫秒值,换算成年就是表示69年的时间。
10 bit:记录工做机器id,表明的是这个服务最多能够部署在2^10台机器上哪,也就是1024台机器。可是10 bit里5个bit表明机房id,5个bit表明机器id。意思就是最多表明2 ^ 5个机房(32个机房),每一个机房里能够表明2 ^ 5个机器(32台机器)。
12 bit:这个是用来记录同一个毫秒内产生的不一样id,12 bit能够表明的最大正整数是2 ^ 12 - 1 = 4096,也就是说能够用这个12bit表明的数字来区分同一个毫秒内的4096个不一样的id
64位的long型的id,64位的long -> 二进制
0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000
2018-01-01 10:00:00 -> 作了一些计算,再换算成一个二进制,41bit来放 -> 0001100 10100010 10111110 10001001 01011100 00
机房id,17 -> 换算成一个二进制 -> 10001
机器id,25 -> 换算成一个二进制 -> 11001
snowflake算法服务,会判断一下,当前这个请求是不是,机房17的机器25,在2175/11/7 12:12:14时间点发送过来的第一个请求,若是是第一个请
假设,在2175/11/7 12:12:14时间里,机房17的机器25,发送了第二条消息,snowflake算法服务,会发现说机房17的机器25,在2175/11/7 12:12:14时间里,在这一毫秒,以前已经生成过一个id了,此时若是你同一个机房,同一个机器,在同一个毫秒内,再次要求生成一个id,此时我只能把加1
0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000001
好比咱们来观察上面的那个,就是一个典型的二进制的64位的id,换算成10进制就是910499571847892992。运维

怎么说呢,大概这个意思吧,就是说41 bit,就是当前毫秒单位的一个时间戳,就这意思;而后5 bit是你传递进来的一个机房id(可是最大只能是32之内),5 bit是你传递进来的机器id(可是最大只能是32之内),剩下的那个10 bit序列号,就是若是跟你上次生成id的时间还在一个毫秒内,那么会把顺序给你累加,最多在4096个序号之内。
因此你本身利用这个工具类,本身搞一个服务,而后对每一个机房的每一个机器都初始化这么一个东西,刚开始这个机房的这个机器的序号就是0。而后每次接收到一个请求,说这个机房的这个机器要生成一个id,你就找到对应的Worker,生成。
他这个算法生成的时候,会把当前毫秒放到41 bit中,而后5 bit是机房id,5 bit是机器id,接着就是判断上一次生成id的时间若是跟此次不同,序号就自动从0开始;要是上次的时间跟如今仍是在一个毫秒内,他就把seq累加1,就是自动生成一个毫秒的不一样的序号。
这个算法那,能够确保说每一个机房每一个机器每一毫秒,最多生成4096个不重复的id。
利用这个snowflake算法,你能够开发本身公司的服务,甚至对于机房id和机器id,反正给你预留了5 bit + 5 bit,你换成别的有业务含义的东西也能够的。
这个snowflake算法相对来讲仍是比较靠谱的,因此你要真是搞分布式id生成,若是是高并发啥的,那么用这个应该性能比较好,通常每秒几万并发的场景,也足够你用了。


5.mysql的主从同步与读写分离
(1)如何实现mysql的读写分离?
其实很简单,就是基于主从复制架构,简单来讲,就搞一个主库,挂多个从库,而后咱们就单单只是写主库,而后主库会自动把数据给同步到从库上去。
(2)MySQL主从复制原理的是啥?
主库将变动写binlog日志,而后从库链接到主库以后,从库有一个IO线程,将主库的binlog日志拷贝到本身本地,写入一个中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog,而后执行binlog日志中的内容,也就是在本身本地再次执行一遍SQL,这样就能够保证本身跟主库的数据是同样的。
这里有一个很是重要的一点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操做,在从库上会串行执行。因此这就是一个很是重要的点了,因为从库从主库拷贝日志以及串行执行SQL的特色,在高并发场景下,从库的数据必定会比主库慢一些,是有延时的。因此常常出现,刚写入主库的数据多是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。
并且这里还有另一个问题,就是若是主库忽然宕机,而后刚好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。
因此mysql实际上在这一块有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。
这个所谓半同步复制,semi-sync复制,指的就是主库写入binlog日志以后,就会将强制此时当即将数据同步到从库,从库将日志写入本身本地的relay log以后,接着会返回一个ack给主库,主库接收到至少一个从库的ack以后才会认为写操做完成了。

所谓并行复制,指的是从库开启多个线程,并行读取relay log中不一样库的日志,而后并行重放不一样库的日志,这是库级别的并行。
1)主从复制的原理
2)主从延迟问题产生的缘由
3)主从复制的数据丢失问题,以及半同步复制的原理
4)并行复制的原理,多库并发重放relay日志,缓解主从延迟问题

(3)mysql主从同步延时问题(精华)

线上确实处理过由于主从同步延时问题,致使的线上的bug,小型的生产事故
show status,Seconds_Behind_Master,你能够看到从库复制主库的数据落后了几ms
其实这块东西咱们常常会碰到,就好比说用了mysql主从架构以后,可能会发现,刚写入库的数据结果没查到,结果就完蛋了。。。。
因此实际上你要考虑好应该在什么场景下来用这个mysql主从同步,建议是通常在读远远多于写,并且读的时候通常对数据时效性要求没那么高的时候,用mysql主从同步
因此这个时候,咱们能够考虑的一个事情就是,你能够用mysql的并行复制,可是问题是那是库级别的并行,因此有时候做用不是很大
因此这个时候。。一般来讲,咱们会对于那种写了以后立马就要保证能够查到的场景,采用强制读主库的方式,这样就能够保证你确定的能够读到数据了吧。其实用一些数据库中间件是没问题的。

通常来讲,若是主从延迟较为严重
一、分库,将一个主库拆分为4个主库,每一个主库的写并发就500/s,此时主从延迟能够忽略不计
二、打开mysql支持的并行复制,多个库并行复制,若是说某个库的写入并发就是特别高,单库写并发达到了2000/s,并行复制仍是没意义。28法则,不少时候好比说,就是少数的几个订单表,写入了2000/s,其余几十个表10/s。
三、重写代码,写代码的同窗,要慎重,当时咱们其实短时间是让那个同窗重写了一下代码,插入数据以后,直接就更新,不要查询
四、若是确实是存在必须先插入,立马要求就查询到,而后立马就要反过来执行一些操做,对这个查询设置直连主库。
不推荐这种方法,你这么搞致使读写分离的意义就丧失了


6.mysql何时建立索引
1.索引是一套数据结构
2.优点:查询快/劣势:下降更新表的速度,写操做慢,查操做快,两套数据
3.什么状况下建立索引
主键自动创建惟一索引
频繁做为查询条件的字段建立索引
外键关系建立索引
单键/组合索引的选择问题,组合索引性价比更高
查询中排序的字段,排序字段若经过索引去访问将大大提升排序速度
查询中统计或者分组字段 group by/order by


7.mysql索引底层数据结构与算法

索引的数据结构 二叉树/HASH/BTREEBtree 度(Degree)-节点的数据存储个数 横向变长,高度变少,节点查找是在内存里一次IO是4K数据,节点的度就是4K数据B+Tree 非叶子节点不存储data,只存储key,能够增大度通常使用磁盘IO次数评价索引结构的优劣myisam索引实现 存储引擎是表级别索引和数据是分离的 叶子节点存的是文件指针不是数据主键索引/非主键索引/分开存储的innodb 主键索引 数据文件自己就是索引文件 叶子节点存储就是数据innodb必需要有主键 整型自增主键非主键索引叶子节点存储的是主键,并非数据,须要查找2次才能找到数据联合索引的底层存储结构同上

相关文章
相关标签/搜索