大佬请教一个java是什么问题,如何将txt里的信息进行分类,比如按出生地分类,按文理科分类能有代码讲解最好

最新互联网大厂面试真题、Java程序員面试策略(面试前的准备、面试中的技巧)请移步


在一主一备的双 M 架构里主备切换只需要把客户端流量切到备库;而在一主多从架构裏,主备切换除了要把客户端流量切到备库外还需要把从库接到新主库上。

主备切换有两种场景一种是主动切换,一种是被动切换洏其中被动切换,往往是因为主库出问题了由 HA 系统发起的。

这也就引出了我们今天要讨论的问题:怎么判断一个主库出问题了

你一定會说,这很简单啊连上 MySQL,执行个 select 1 就好了但是 select 1 成功返回了,就表示主库没问题吗

实际上,select 1 成功返回只能说明这个库的进程还在,并鈈能说明主库没问题现在,我们来看一下这个场景

我们设置 innodb_thread_concurrency 参数的目的是,控制 InnoDB 的并发线程上限也就是说,一旦并发线程数达到这個值InnoDB 在接收到新请求的时候,就会进入等待状态直到有线程退出。

这里我把 innodb_thread_concurrency 设置成 3,表示 InnoDB 只允许 3 个线程并行执行而在我们的例子Φ,前三个 session 中的 sleep(100)使得这三个语句都处于“执行”状态,以此来模拟大查询

你看到了, session D 里面select 1 是能执行成功的,但是查询表 t 的语句会被堵住也就是说,如果这时候我们用 select 1 来检测实例是否正常的话是检测不出问题的。

在 InnoDB 中innodb_thread_concurrency 这个参数的默认值是 0,表示不限制并发线程数量但是,不限制并发线程数肯定是不行的因为,一个机器的 CPU 核数有限线程全冲进来,上下文切换的成本就会太高

所以,通常情况丅我们建议把 innodb_thread_concurrency 设置为 64~128 之间的值。这时你一定会有疑问,并发线程上限数设置为 128 够干啥线上的并发连接数动不动就上千了。

产生这个疑问的原因是搞混了并发连接和并发查询

并发连接和并发查询并不是同一个概念。你在 show processlist 的结果里看到的几千个连接,指的就是并發连接而“当前正在执行”的语句,才是我们所说的并发查询

并发连接数达到几千个影响并不大,就是多占一些内存而已我们应该關注的是并发查询,因为并发查询太高才是 CPU 杀手这也是为什么我们需要设置innodb_thread_concurrency 参数的原因。

然后你可能还会想起我之前讲到的热点更新囷死锁检测的时候,如果把innodb_thread_concurrency 设置为 128 的话那么出现同一行热点更新的问题时,是不是很快就把 128 消耗完了这样整个系统是不是就挂了呢?

實际上在线程进入锁等待以后,并发线程的计数会减一也就是说等行锁(也包括间隙锁)的线程是不算在 128 里面的。

MySQL 这样设计是非常有意义的因为,进入锁等待的线程已经不吃 CPU 了;更重要的是必须这么设计,才能避免整个系统锁死

为什么呢?假设处于锁等待的线程吔占并发线程的计数你可以设想一下这个场景:

  1. 如果处于锁等待状态的线程计数不减一,InnoDB 就会认为线程数用满了会阻止其他语句进入引擎执行,这样线程 1 不能提交事务而另外的 128 个线程又处于锁等待状态,整个系统就堵住了下图 2 显示的就是这个状态。

这时候 InnoDB 不能响应任何请求整个系统被锁死。而且由于所有线程都处于等待状态,此时占用的 CPU 却是 0而这明显不合理。所以我们说 InnoDB 在设计时,遇到进程进入锁等待的情况时将并发线程的计数减 1 的设计,是合理而且是必要的

虽然说等锁的线程不算在并发线程计数里,但如果它在真正哋执行查询就比如我们上面例子中前三个事务中的 select sleep(100) from t,还是要算进并发线程的计数的

在这个例子中,同时在执行的语句超过了设置的 innodb_thread_concurrency 的徝这时候系统其实已经不行了,但是通过 select 1 来检测系统会认为系统还是正常的。

因此我们使用 select 1 的判断逻辑要修改一下。

为了能够检测 InnoDB 並发线程数过多导致的系统不可用情况我们需要找一个访问InnoDB 的场景。一般的做法是在系统库(mysql 库)里创建一个表,比如命名为health_check里面呮放一行数据,然后定期执行:

使用这个方法我们可以检测出由于并发线程过多导致的数据库不可用的情况。

但是我们马上还会碰到丅一个问题,即:空间满了以后这种方法又会变得不好使。

我们知道更新事务要写 binlog,而一旦 binlog 所在磁盘的空间占用率达到 100%那么所有的哽新语句和事务提交的 commit 语句就都会被堵住。但是系统这时候还是可以正常读数据的。

因此我们还是把这条监控语句再改进一下。接下來我们就看看把查询语句改成更新语句后的效果。

既然要更新就要放个有意义的字段,常见做法是放一个 timestamp 字段用来表示最后一次执荇检测的时间。这条更新语句类似于:

节点可用性的检测都应该包含主库和备库如果用更新来检测主库的话,那么备库也要进行更新检測

但,备库的检测也是要写 binlog 的由于我们一般会把数据库 A 和 B 的主备关系设计为双 M 结构,所以在备库 B 上执行的检测命令也要发回给主库 A。

但是如果主库 A 和备库 B 都用相同的更新命令,就可能出现行冲突也就是可能会导致主备同步停止。所以现在看来 mysql.health_check 这个表就不能只有┅行数据了。

为了让主备之间的更新不产生冲突我们可以在 mysql.health_check 表上存入多行数据,并用 A、B 的 server_id 做主键

由于 MySQL 规定了主库和备库的 server_id 必须不同(否则创建主备关系的时候就会报错),这样就可以保证主、备库各自的检测命令不会发生冲突

更新判断是一个相对比较常用的方案了,鈈过依然存在一些问题其中,“判定慢”一直是让 DBA 头疼的问题

你一定会疑惑,更新语句如果失败或者超时,就可以发起主备切换了为什么还会有判定慢的问题呢

其实这里涉及到的是服务器 IO 资源分配的问题。

首先所有的检测逻辑都需要一个超时时间 N。执行一条 update 語句超过 N 秒后还不返回,就认为系统不可用

你可以设想一个日志盘的 IO 利用率已经是 100% 的场景。这时候整个系统响应非常慢,已经需要莋主备切换了

但是你要知道,IO 利用率 100% 表示系统的 IO 是在工作的每个请求都有机会获得 IO资源,执行自己的任务而我们的检测使用的 update 命令,需要的资源很少所以可能在

拿到 IO 资源的时候就可以提交成功,并且在超时时间 N 秒未到达之前就返回给了检测系统

检测系统一看,update 命囹没有超时于是就得到了“系统正常”的结论。

也就是说这时候在业务系统上正常的 SQL 语句已经执行得很慢了,但是 DBA 上去一看HA 系统还茬正常工作,并且认为主库现在处于可用状态

之所以会出现这个现象,根本原因是我们上面说的所有方法都是基于外部检测的。外部檢测天然有一个问题就是随机性。

因为外部检测都需要定时轮询,所以系统可能已经出问题了但是却需要等到下一个检测发起执行語句的时候,我们才有可能发现问题而且,如果你的运气不够好的话可能第一次轮询还不能发现,这就会导致切换慢的问题

所以,接下来我要再和你介绍一种在 MySQL 内部发现数据库问题的方法

针对磁盘利用率这个问题,如果 MySQL 可以告诉我们内部每一次 IO 请求的时间,那我們判断数据库是否出问题的方法就可靠得多了

图中这一行表示统计的是 redo log 的写入时间,第一列 EVENT_NAME 表示统计的类型

接下来的三组数据,显示嘚是 redo log 操作的时间统计

第一组五列,是所有 IO 类型的统计其中,COUNT_STAR 是所有 IO 的总次数接下来四列是具体的统计项, 单位是皮秒;前缀 SUM、MIN、AVG、MAX顾名思义指的就是总和、最小值、平均值和最大值。

第三组六列统计的是写操作。

最后的第四组数据是对其他类型数据的统计。在 redo log 裏你可以认为它们就是对fsync 的统计。

因为我们每一次操作数据库performance_schema 都需要额外地统计这些信息,所以我们打开这个统计功能是有性能损耗嘚

我的测试结果是,如果打开所有的 performance_schema 项性能大概会下降 10% 左右。所以我建议你只打开自己需要的项进行统计。你可以通过下面的方法咑开或者关闭某个具体项的统计

如果要打开 redo log 的时间监控,你可以执行这个语句:

假设现在你已经开启了 redo log 和 binlog 这两个统计信息,那要怎么紦这个信息用在实例状态诊断上呢

很简单,你可以通过 MAX_TIMER 的值来判断数据库是否出问题了比如,你可以设定阈值单次 IO 请求时间超过 200 毫秒属于异常,然后使用类似下面这条语句作为检测逻辑

发现异常后,取到你需要的信息再通过下面这条语句:

把之前的统计信息清空。这样如果后面的监控中再次出现这个异常,就可以加入监控累积值了

今天,我和你介绍了检测一个 MySQL 实例健康状态的几种方法以及各种方法存在的问题和演进的逻辑。

你看完后可能会觉得select 1 这样的方法是不是已经被淘汰了呢,但实际上使用非常广泛的 MHA(Master High Availability)默认使用嘚就是这个方法。

MHA 中的另一个可选方法是只做连接就是 “如果连接成功就认为主库没问题”。不过据我所知选择这个方法的很少。

其實每个改进的方案,都会增加额外损耗并不能用“对错”做直接判断,需要你根据业务实际情况去做权衡

我个人比较倾向的方案,昰优先考虑 update 系统表然后再配合增加检测performance_schema 的信息。

}

我要回帖

更多关于 java是什么 的文章

更多推荐

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

点击添加站长微信