• [云日志] 简单介绍下logback的SizeAndTimeBasedRollingPolicy的清理机制
    本帖最后由 vincent 于 2018-1-23 20:58 编辑appender name="test" class="ch.qos.logback.core.rolling.RollingFileAppender"> file>test/test.logfile> rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> fileNamePattern>test/test.%d{yyyy-MM-dd}.%i.logfileNamePattern> maxHistory>3maxHistory> totalSizeCap>100MBtotalSizeCap> maxFileSize>10MBmaxFileSize>rollingPolicy> encoder> Pattern>${ENCODER_PATTERN}Pattern>encoder>appender> 1.只有日志触发滚动,才会启动清理机制,当然我们可以配置进程启动时触发清理: cleanHistoryOnStart>truecleanHistoryOnStart>2. 先按照时间维度清理(一天只会触发一次,除非进程重启):3 这个参数决定了日志文件保留的历史,但是并不意味着手动创建一个1个月前的日志文件(或者说由于某些原因一个月前的文件没有及时删除)此时也能够被清除, 因为按照时间维度能够清理的最早日志文件是35(3+32)天前的日志3. 再根据日志总量来清理,100MB,日志总量的清理只会计算三天内的日志(3)总量是否达到100MB,所以说 总量的清理机制并不是按照目录下所有文件的总量来清理的
  • [技术干货] MySQL半同步复制演进
    1 介绍MySQL 提供了异步复制,主库并不关心备库是否收到日志,从而可能导致较多的数据丢失。从MySQL5.5开始引入了一种半同步复制功能,该功能可以确保主服务器和至少一台从服务器之间的数据一致性和冗余,从而可以减少数据的丢失。1.1 异步复制 master将binlog event发送给slave后,不去确认slave是否已经收到就返回成功给客户端。80301.2 半同步复制 master将binlog event发送给slave后,确认slave已经收到时才返回成功给客户端。 80312 半同步复制演进2.1 减少LOCK_log锁冲突在MySQL5.7.2版本中重构DUMP线程减小了LOCK_log锁冲突。 在之前版本中,写binlog的设计为先持有LOCK_log锁(锁住了整个binlog文件),写完后释放锁,再发送binlog更新信号。DUMP线程在读取binlog内容时,也要先获取到LOCK_log锁,然后读取binlog内容,然后释放锁。这样当写binlog的线程和DUMP线程在处理同一个binlog时,就会有较严重的冲突。 在MySQL5.7中调整了这块的设计。因为写binlog时是追加写入,DUMP线程只是读取,这样可以用一个变量(binlog_end)记录binlog文件末尾位置,每次追加写入后更新下这个变量就可以(用lock_binlog_end锁保护变量binlog_end),DUMP线程在读取时只要不超过标记的binlog末尾位置就可以。只需要在读取到末尾位置时,获取下lock_binlog_end锁,获取下最新的末尾位置。2.2 半同步复制等待点调整 在MySQL5.6版本中,master将每个事物写入binlog传递到slave刷新到磁盘(relay log),同时主库提交事务。master等待slave 反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。 这样主库返回给客户端commit ok前,可能事物已经真正提交了,但是从库还没有收到日志。这时其他客户端已经可以看到了提交的事物,这时如果主库故障,主备切换后,其他客户端发现刚才提交的事物又消失了。 为了解决这个问题MySQL在5.7.2中有了一个解决方案” transaction loss-less”.具体逻辑为master将每个事务写入binlog , 传递到slave刷新到磁盘(relay log)。master等待slave反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。同时引入了参数rpl_semi_sync_master_wait_point来控制使用的策略,默认值为AFTER_SYNC,即5.7的改进做法,还有一个可选值为AFTER_COMMIT,即5.6中的策略。MySQL5.6处理逻辑图:8032MySQL5.7.2处理逻辑图:80332.3 独立线程处理ACKMySQL5.6的semi sync 受限于dump thread,原因是dump thread 承担了两份不同且又十分频繁的任务:传送binlog给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制会影响数据库整体的TPS 。8034为了解决上述问题,在5.7.4版本的semi sync框架中,独立出一个 ack collector thread ,专门用于接收slave的反馈信息。这样master 上有两个线程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。80352.4 master支持等待多个slave在MySQL5.6中当半同步开启时,master只是保证一个slave接收到日志,这样当在一主多从的场景下,master和接收到最新日志的slave都挂掉了,那就会丢失数据。这样增加多个备库也不会提高HA的可用性。在MySQL5.7.3中新增了参数rpl_semi_sync_master_wait_slave_count,可以用来控制master需要保证多少个slave接收到日志。
  • [云监控] 主机监控的信息都是总量,能不能更细一些啊,比如进程级别的
    主机监控的信息都是总量,能不能更细一些啊,比如进程级别的
  • [技术分享] 浅谈接口性能测试中模拟客户端的两种模式
    本帖最后由 kehaar 于 2017-12-29 11:24 编辑性能测试中,常见的一种场景是测试系统在大量请求下的响应能力和系统指标。因此,对性能测试来说,不可缺少的就是使用某种方法构造大量请求。 构造大量并发请求的工具,基本可以分为2种模式:1、 请求后,等待被测对象的响应后,继续下一次请求。这种方式我们称之为“乒乓球”模式,为了构造大量请求,通常使用多线程/协程并发请求,但每个线程/协程仍遵循“请求-等待响应”的“乒乓球”模式。2、 请求后,不等待被测对象的响应,而是直接继续请求。这种方式我们称之为“机关枪”模式。下面从几个不同角度对比两种模式: 1、适用范围:“乒乓球”模式更模拟正常客户端交互的行为,因此可以适用于各种被测对象,而“机关枪”模式只能适用于客户端与服务端不建立连接的场景,因此对于一些的简单的协议,如DNS等,适合使用“机关枪”模式 2、资源占用:“乒乓球”模式在请求发出到收到响应之间,会持续占用一定资源,因此占用资源较多,这点在被测系统性能恶化的情况下会尤为突出,而“机关枪”模式不等待和处理响应,因此占用资源较少,性能较好,在相同客户端硬件条件下可以提供更高的每秒请求量。 3、构造测试场景的难度:理论上来说“乒乓球”模式的行为更接近于真实客户端的行为,但是对于同时请求的客户端较多的场景,受限于性能,很难用“乒乓球”模式运行真实的客户端数量的线程/协程,而是通过减小请求时延的方式来模拟,举例来说: 测试某系统处理每秒1k请求的场景,从用户行为分析,每个用户约30s会请求一次系统,那么实际上在30s内,其实是有3w个不同的客户端在访问系统。此时最符合真实场景的模拟方式应该是:3W个“乒乓球”模式的客户端,每个客户端每次请求相差30s但是由于乒乓球”模式较占用资源,这种模拟场景很难达成,那么一般会使用减小时延和并发线程数的方式,例如:1k个“乒乓球”模式的客户端,并通过添加适当时延保证每秒请求数为1k这种模拟方式存在一个弊端:当被测对象的性能恶化(响应时长变长)时,请求的频率将得不到保证,对上面的例子来说,如果被测对象的平均响应时间达到1s以上,那就无法维持1k/s的频率,此时为了达到1k/s的频率,就必须增加并发线程/协程数,而并发线程数的增加又可能进一步导致被测对象的性能恶化,同时也会消耗更多的模拟客户端(测试工具)的性能。特别是在使用多测试客户端分布式访问被测对象时,对一个测试客户端参数的调整将导致其他被测对象响应时间的变化,从而影响其他测试客户端对象的请求频率。这使得测试人员花费过多时间在调整并发线程/协程数和时延参数上,难以轻松构造希望的压力场景 而如果使用“机关枪”模式,则客户端的行为可大幅简化,例如:100个“机关枪”模式的客户端,每个请求之间相差0.1s这个实现只依赖与客户端发送请求本身消耗的时间(这个时间不大于0.1s就可以实现),而与被测对象的响应时间无关,因此也不会受到其他测试客户端的影响。可以简单的构造稳定频率的请求压力 4、结果度量“乒乓球”模式会等待每个请求的响应,因此可以方便的进行测试结果的计算统计,而“机关枪”模式由于不等待响应,因此无法进行结果的计算统计。因此,“机关枪”模式基本不会单独使用,在使用“机关枪”模式构造大压力的背景下,还需要使用一个“乒乓球”模式客户端,以相对极低的qps对系统请求,来度量系统此时的性能。使用这种方式的前提,是小流量“乒乓球”模式客户端和大流量“机关枪”模式客户端的请求对被测对象来说是等同处理的,也就是说:1、两种客户端的请求来自同一个请求集合。2、被测对象没有使用基于IP或端口的的负载均衡方式(或“机关枪”模式客户端的源IP/端口均匀的覆盖了负载均衡的每个后端)3、“机关枪”模式客户端的请求没有触发被测对象基于IP/端口的流控策略 总结如下(红色代表优势):客户端模式“乒乓球”“机关枪”适用范围适用于各种请求并发测试只适用于客户端与服务端不建立连接的简单协议请求资源占用高低构造测试场景的难度需要构造大并发数时较为复杂和不稳定可以简单构造稳定的大并发度量结果可以直接度量测试结果不能单独度量结果,必须结合一个小流量“乒乓球”模式客户端以抽样的方式度量测试结果由此可见,“乒乓球”模式客户端适用场景更广,因此常见的性能测试工具也以“乒乓球”模式为主。然而在特定条件下(无连接的简单协议、大并发)下,使用“机关枪”模式测试工具会更加适合,也更加节省资源。因此在性能测试过程中,我们应该学会根据测试场景的不同选择不同模式的工具。
  • HWSQL线程池实现原理
    本帖最后由 huafengchun 于 2017-12-27 20:03 编辑HWSQL线程池实现原理常见场景 数据库在平时的应用开发中是不可或缺的一部分。但是,随着应用越来越复杂,一个数据库承载的应用数量逐渐增加,数据库性能随着负载的增加而降低。为了解决这个问题,大家可能使用了中间件来管理数据库连接,或者干脆将数据库拆分。但是,使用中间件使用了新的组件,引入了不稳定的风险;数据库拆分又没有充分使用硬件的性能。所以,一款能够使用大量连接,并在大量连接下仍能够保证良好的执行效率的数据库就显得格外重要。那么,为什么数据库性能会随着连接数的增加而降低呢?目前MySQL社区版针对每一个连接都创建一个线程来处理该连接的请求。当并发请求过大时,操作系统会在资源上和线程调度上耗费大量的资源。线程的频繁切换还会带来大量的内存页面失效和CPUcache的不命中,内存换页和重新cache会导致MySQL运行效率大幅度降低。这样,使用线程池的方式处理任务针对大量请求连接变得十分必要。 线程池特性分析 线程池的设计原理为:1) 创建线程池,线程池中有线程组,每个线程组中有若干个线程。2) 网络连接多路复用,循环监听所有套接字,一次获取可读的套接字。3) 针对每一个可读的套接字,从线程池中选择空闲的线程组,处理该请求。4) 处理完成后线程组变为空闲状态,等待新的任务。5) 线程组中有高优先级队列和低优先级队列,已经开始事务或者获得锁的任务更容易被执行,防止大量已经处理但未处理完的半成品。6) 低优先级的任务不会发生过长时间的饥饿,会根据情况切换到高优先级队列中。 以下是连接的处理示意图,能够更加形象的说明该特性的原理。 7840MySQL社区版连接处理示意图 上图为社区版本的连接示意图,MySQL会对每个连接创建一个服务线程,该线程持续等待用户的请求,并负责处理该请求并返回结果。 7841HWSQL线程池对连接的处理示意图 上图为HWSQL线程池处理连接的方式,用户连接由线程池负责调度处理。线程个数由参数配置,不会因为连接数的增加而增加,这样能够提高cache和内存页面的命中率,减少线程切换以及线程本身对系统资源的消耗。 通过Sysbench压力测试可以发现,MySQL社区版的TPS随着连接数的增大先增加后减小,最后降低趋近为0,而使用了线程池的HWSQL的TPS随着连接数的增大而增加,最后保持最大值。 7842HWSQL与社区版读写性能性能对比图 7843HWSQL与社区版只读性能性能对比图 插件形式提供线程池功能 MySQL有一套完善的插件机制,定制化的功能可以使用插件的形式来实现。使用插件可以避免修改MySQL代码和主要流程,降低代码耦合。可以动态加载和卸载,使用灵活。可以对插件进行独立升级,减少代码修改带来的影响。 有关连接管理和调度部分,MySQL已经考虑到了自定义开发,在官方提供的两种调度管理外,还提供了一个抽象类让用户自定义连接的管理方法,以及为插件提供了初始化,去初始化方法。所以,线程池借助了这些便利,使用插件的形式实现是再好不过的了。 HWSQL使用了插件实现线程池,避免大量侵入MySQL原有逻辑。并方便用户进行配置,参数组的开启和关闭使用一个配置即可实现。 性能测试(基于MySQL5.6,性能仍在不断优化提升) Sysbench workload 测试结果 7844784578467847
  • jmeter中token过期处理
    1、在线程组里添加login线程;2、添加”Loop Controller“控制器,通过loop controller设置循环次数(login线程放置在循环控制器上面); 3、循环次数运算方法:将换换控制器的循环次数该为1,并发次数为最终并发次数,执行脚本,记录1次运行完的时间,然后预算出24小时能执行的次数,将计算出的次数写入循环控制器的循环次数中即可;
  • 卸载服务操作需要去启动业务进程吗?
    在可服务性测试过程中遇到一个疑惑:卸载服务时需要去启动业务进程吗?具体的卸载流程是怎么样的呢?哪位大神给解答一下?
  • [行业资讯] linux内存加压原理及具体实现
    在可靠性测试、压力测试中,经常需要模拟内存剩余量很小的场景,以下介绍其原理及具体实现 原理: (1)首先获取当前节点内存剩余量,(Memcache是否作为剩余量可视情况具体确定) (2)将节点内存使用量分为若干份,具体份数可自定义 (3)启动若干个进程,每个进程占用指定量的内存,并设置持续时间 具体实现:以下代码将总内存剩余量分为10份,每份占用内存量为$c;启动9个进程,每个进程占用$c,该节点内存占用率就会达到9/10;持续900s后自动清除
  • 手把手教你用netperf工具测试云主机间网络性能
    本帖最后由 樱桃小丸子 于 2017-12-12 13:55 编辑 1 测试准备1.1 准备弹性云服务器推荐使用CentOS 7.2 64bit镜像,s2.2xlarge.2规格测试。需要分别准备1台被测机及4台加压机。注:测试机与加压机均在同可用区同子网内。 假设被测机及加压机IP如下: 被测机:192.168.2.10 加压机1:192.168.2.11 加压机2:192.168.2.12 加压机3:192.168.2.13 加压机4:192.168.2.141.2 准备测试工具推荐使用netperf工具测试网络性能。如果云主机OS中没有netperf工具,需要云主机能够上Internet从github下载和安装此工具。需要分别在被测机及加压机上安装netperf测试工具。工具下载地址:https://github.com/HewlettPackar ... e/netperf-2.7.0.zip2 TCP带宽测试2.1 测试TCP发包性能测试步骤:1. 分别在4个加压机中执行以下命令netserver进程加压机1:netserver -p 12000加压机2:netserver -p 12000加压机3:netserver -p 12000加压机4:netserver -p 12000 参数备注:-p 监听端口号,与发送端端口号一致。 2. 在测试机中执行如下命令启动4个netperf进程netperf -H 192.168.2.11 -p 12000 -t TCP_STREAM -l 120 -- -m1440netperf -H 192.168.2.12 -p 12000 -t TCP_STREAM -l 120 -- -m1440netperf -H 192.168.2.13 -p 12000 -t TCP_STREAM -l 120 -- -m1440netperf -H 192.168.2.14 -p 12000 -t TCP_STREAM -l 120 -- -m1440 参数备注:-H 接收端IP地址 -p 端口号 -t 发包协议类型,可以是TCP_STREAM或者UDP_STREAM -l 测试时长 -m 数据包大小。建议测试PPS时设为64,测试bps时设为1440 2.2 测试TCP收包性能测试步骤:1. 执行以下命令在测试机中启动4个netserver进程netserver -p 12000netserver -p 12001netserver -p 12002netserver -p 12003 2. 分别在4个加压机中启动netperf进程加压机1:netperf -H 192.168.2.10 -p 12000 -t TCP_STREAM-l 120 -- -m 1440加压机2:netperf -H 192.168.2.10 -p 12001 -tTCP_STREAM -l 120 -- -m 1440加压机3:netperf -H 192.168.2.10 -p 12002 -tTCP_STREAM -l 120 -- -m 1440加压机4:netperf -H 192.168.2.10 -p 12003 -tTCP_STREAM -l 120 -- -m 1440 2.3 TCP测试结果解析测试结束后,发送端netperf进程输出结果如图1所示,最终结果为所有netperf进程测试结果之和。图1:TCP测试结果示例6491 3 UDP PPS测试3.1 测试UDP发包性能测试步骤:1. 分别在每个加压机中执行以下命令启动1个netserver进程加压机1:netserver -p 12000加压机2:netserver -p 12000加压机3:netserver -p 12000加压机4:netserver -p 120002. 在测试机中执行如下命令启动4个netperf进程netperf -H 192.168.2.11 -p 12000 -t UDP_STREAM -l 120 -- -m64netperf -H 192.168.2.12 -p 12000 -t UDP_STREAM -l 120 -- -m64netperf -H 192.168.2.13 -p 12000 -t UDP_STREAM -l 120 -- -m64netperf -H 192.168.2.14 -p 12000 -t UDP_STREAM -l 120 -- -m643.2 测试UDP收包性能测试步骤:1. 执行以下命令在测试机中启动8个netserver进程netserver -p 12000netserver -p 12001netserver -p 12002netserver -p 12003netserver -p 12004netserver -p 12005netserver -p 12006netserver -p 120072. 分别在每个加压机中启动2个netperf进程加压机1:netperf -H 192.168.2.10 -p 12000 -tUDP_STREAM -l 120 -- -m 64 netperf -H192.168.2.10 -p 12001 -t UDP_STREAM -l 120 -- -m 64加压机2:netperf -H 192.168.2.10 -p 12002 -tUDP_STREAM -l 120 -- -m 64 netperf -H 192.168.2.10 -p 12003-tUDP_STREAM -l 120 -- -m 64加压机3:netperf -H 192.168.2.10 -p 12004 -tUDP_STREAM -l 120 -- -m 64 netperf -H192.168.2.10 -p 12005 -t UDP_STREAM -l 120 -- -m 64加压机4:netperf -H 192.168.2.10 -p 12006 -tUDP_STREAM -l 120 -- -m 64 netperf -H192.168.2.10 -p 12007 -t UDP_STREAM -l 120 -- -m 643.3 UDP 测试结果测试结束后,发送端单个netperf进程输出结果如图2所示,最终结果为所有netperf进程测试结果总和。 图2:UDP测试结果示例6492 注:PPS= 数据包成功数/测试时间
  • jmeter使用中的问题
    使用正则表达式获取返回体中的数据,并发>2,其中有一次返回为空时不能覆盖不为空的情况,导致获取不能根据返回体为空进行别的进程运行,这个问题可以在后置处理器中使用代码可给给空的返回体赋不为空的值(其中的格式获取方式自己研究),然后进行后续的进程;if(返回体.equals("[]")){ vars.put("变量名","变量值"); }
  • 使用fastunit编写自动化脚本的童鞋欢迎赐教
    问题描述:近日,新增服务自动化新需求后,自动化任务出现线程不足的情况,阻塞自动化任务连跑,与fastunit工具负责人沟通后,定位原因为fastunit线程池的大小是由用例数量和用例步骤共同决定的,新增自动化用例之后,执行到一定数量后,线程无法启动,自动化阻塞,已联系跟进负责人优化工具,近日,我应该如何在用例中将新需求即实现用例之间的解耦,又减少用例的步骤,避免类似的情况发生。
  • [云日志] [云日志]如果你也好奇日志服务后端如何做到平滑停机
    在日志服务中,我们使用了 kafka 作为消息中间件,日志数据会首先暂存在消息队列中,然后消费者再根据后端业务的处理能力,逐步消费这些日志数据。采用消息队列,能够做到前后端业务解耦,对外的接口可以提供高吞吐量,内部业务系统可以根据实际处理能力,对消息进行消费处理。 在服务端,我们的消费者从 kafka 中取出消息,然后累积至一定的数量,再批量提交至服务端的业务系统。不同的业务系统,批量处理能力不同,每个业务系统会建立各自的线程池与kafka交互。 4948 kafka 与我们的业务系统对接采用典型的分布式部署方式,kafka 采用三节点部署组成集群,业务系统每个集群至少为两个节点,避免单点故障。由于在业务系统中,我们缓存了部分数据,因此面临一个重要的问题就是:如何在系统升级时,重启应用做到内存中的数据不丢失? 解决的方式很简单,在程序启动的时候,注册shutdown hook,通过该shutdown hook,程序就可以接收进程停止的信号。在接收到该信号之后,通知业务线程,不再处理新的请求或者接收新的事件,并把内存中缓存的数据消费处理完就可以了。4949在这个处理环节中,我们在程序中创建了一个“生命周期管理器”,所有的业务线程在启动的时候,首先将自己注册到管理器中,然后才进行业务处理(事件监听、接收请求等)。当要进行程序停止(升级操作)时,通过外部的启停脚本,给该进程发送TERM信号(kill / kill –TERM )。Hook线程接收到该信号之后,通知“生命周期管理器”,然后等待其处理结束。注意:这里必须等待生命周期管理器处理完成,否则程序会立即结束。在管理器里,我们最开始是顺序遍历所有的业务线程,调用业务线程的stop方法,通过但是由于业务线程量比较大,如果等待所有的线程结束,整体时间是不可控的。改进后的方案是,在顺序遍历所有业务线程时,new新的线程用于执行原有业务线程的stop方法,这种做法相当于并发的将stop命令通知到所有的业务线程。在下发stop命令的同时,我们传入一个计数器给该业务线程,在业务线程的stop方法结束时,该计数器减1,计数器的大小是所有业务线程的个数,这样当该计数器为0的时候,可以认为所有的业务线程已经正常停止,就可以真正的停止程序。以上是我们服务端的平滑停机的一些实践,由于经验有限,还希望大家多多提意见。
  • [云监控] 【新功能预告】虚拟机进程监控即将上线!
    你还在用shell脚本来查看进程性能监控数据吗? 你还在满世界找开源监控工具吗? 你还在为进程的异常问题担惊受怕吗? CES服务即将上线的系统进程监控功能完美的解决您的烦恼!! 1. 系统进程实时查看,你可以配置查看所有系统/业务进程作为监控对象。当然了,你在查看到系统监控数据前需要安装Telescope插件。 2. 支持查看某一进程相关联进程的性能数据。 3. 您可以选择对系统所有进程来进行监控,当然初期可能会在进程数上有所限制。
  • [技术干货] root密码忘记如何处理
    一、MySQL5.6方面:当最高权限的用户密码root备忘记后,可以按如下方式来处理1. 关闭mysql进程2. 在/etc/my.cnf配置文件中加上 skip-grant-tables 3. 启动mysql进程4. 修改密码 47763. 将skip-grant-tables从配置文件中删除4. 重启mysql进程 二、MySQL5.7方面:如果还是按同样的方法,则会报错...4777 需要使用下面的方法:4778
  • [技术干货] MySQL的内存使用分析
    这个公式只能计算出应用并发跑满的最极端情况下,mysql使用的内存的最大值。这个值的意义不大。我其实是想弄明白一个连接进来不执行任何操作(空连接),mysql或者操作系统会为这个连接分配多少内存,分配的内存包含哪些部分。 Memories for variablesread_buffer_size, sort_buffer_size, read_rnd_buffer_size, tmp_table_size areallocated as & when required.根据上边这段话的意思,建立一个空连接只需要分配 thread_stack+net_buffer_length这么多空间。我怎么去验证这个问题?从内存的使用方式MySQL 数据库的内存使用主要分为以下两类:线程独享内存 和 全局共享内存 Mysql Server Memory Usage= Sum of Global Buffers + (number of Connection * Per thread memory variables). 线程独享内存名称意义对应MySQL参数备注线程栈信息使用内存主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等,我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。thread_stack排序使用内存MySQL用此内存区域进行排序操作(filesort),完成客户端的排序请求。当我们设置的排序区缓存大小无法满足排序实际所需内存的时候,MySQL会将数据写入磁盘文件来完成排序。由于磁盘和内存的读写性能完全不在一个数量级,所以sort_buffer_size参数对排序操作的性能影响绝对不可小视。sort_buffer_sizeJoin操作使用内存应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/indexjoin),为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作。当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。join_buffer_size顺序读取数据缓冲区使用内存这部分内存主要用于当需要顺序读取数据的时候,如无发使用索引的情况下的全表扫描,全索引扫描等。在这种时候,MySQL按照数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在read_buffer_size中,当 buffer空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调用者,以提高效率。read_buffer_size随机读取数据缓冲区使用内存和顺序读取相对应,当MySQL进行非顺序读取(随机读取)数据块的时候,会利用这个缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进行Join等等。总的来说,就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取,进而使用到 read_rnd_buffer_size参数所设置的内存缓冲区。read_rnd_buffer_size连接信息及返回客户端前结果集暂存使用内存这部分用来存放客户端连接线程的连接信息和返回客户端的结果集。当 MySQL 开始产生可以返回的结果集,会在通过网络返回给客户端请求线程之前,会先暂存在通过net_buffer_size所设置的缓冲区中,等满足一定大小的时候才开始向客户端发送,以提高网络传输效率。不过,net_buffer_size参数所设置的仅仅只是该缓存区的初始化大小,MySQL 会根据实际需要自行申请更多的内存以满足需求,但最大不会超过max_allowed_packet 参数大小。net_buffer_length没有net_buffer_size参数批量**暂存使用内存当我们使用如 insert …values(…),(…),(…)… 的方式进行批量**的时候,MySQL会先将提交的数据放如一个缓存空间中,当该缓存空间被写满或者提交完所有数据之后,MySQL才会一次性将该缓存空间中的数据写入数据库并清空缓存。此外,当我们进行 LOAD DATA INFILE 操作来将文本文件中的数据 Load进数据库的时候,同样会使用到此缓冲区。bulk_insert_buffer_size临时表使用内存当我们进行一些特殊操作如需要使用临时表才能完成的Order By,Group By 等等,MySQL 可能需要使用到临时表。当我们的临时表较小(小于 tmp_table_size参数所设置的大小)的时候,MySQL 会将临时表创建成内存临时表,只有当 tmp_table_size所设置的大小无法装下整个临时表的时候,MySQL 才会将该表创建成 MyISAM 存储引擎的表存放在磁盘上。不过,当另一个系统参数max_heap_table_size 的大小还小于 tmp_table_size 的时候,MySQL 将使用max_heap_table_size 参数所设置大小作为最大的内存临时表大小,而忽略 tmp_table_size 所设置的值。而且tmp_table_size 参数从 MySQL 5.1.2 才开始有,之前一直使用 max_heap_table_size。tmp_table_size上面所列举的 MySQL 线程独享内存仅仅只是所有线程独享内存中的部分,并不是全部,选择的原则是可能对MySQL 的性能产生较大的影响,且可以通过系统参数进行调节。由于以上内存都是线程独享,极端情况下的内存总体使用量将是所有连接线程的总倍数。所以各位朋友在设置过程中一定要谨慎,切不可为了提升性能就盲目的增大各参数值,避免因为内存不够而产生Out Of Memory 异常或者是严重的 Swap 交换反而降低整体性能。 全局共享内存名称意义对应MySQL参数备注查询缓存查询缓存是 MySQL 比较独特的一个缓存区域,用来缓存特定Query 的结果集(Result Set)信息,且共享给所有客户端。通过对 Query 语句进行特定的 Hash 计算之后与结果集对应存放在Query Cache 中,以提高完全相同的 Query 语句的相应速度。当我们打开 MySQL 的 Query Cache 之后,MySQL接收到每一个 SELECT 类型的 Query 之后都会首先通过固定的 Hash 算法得到该 Query 的 Hash 值,然后到 QueryCache 中查找是否有对应的 Query Cache。如果有,则直接将 Cache的结果集返回给客户端。如果没有,再进行后续操作,得到对应的结果集之后将该结果集缓存到 Query Cache中,再返回给客户端。当任何一个表的数据发生任何变化之后,与该表相关的所有 Query Cache 全部会失效,所以 Query Cache对变更比较频繁的表并不是非常适用,但对那些变更较少的表是非常合适的,可以极大程度的提高查询效率,如那些静态资源表,配置表等等。为了尽可能高效的利用 Query Cache,MySQL 针对 Query Cache 设计了多个 query_cache_type 值和两个 QueryHint:SQL_CACHE 和 SQL_NO_CACHE。当 query_cache_type 设置为0(或者 OFF)的时候不使用Query Cache,当设置为1(或者 ON)的时候,当且仅当 Query 中使用了 SQL_NO_CACHE 的时候 MySQL 会忽略Query Cache,当 query_cache_type 设置为2(或者DEMAND)的时候,当且仅当Query 中使用了SQL_CACHE 提示之后,MySQL 才会针对该 Query 使用 Query Cache。可以通过 query_cache_size来设置可以使用的最大内存空间。query_cache_size连接线程缓存连接线程是 MySQL为了提高创建连接线程的效率,将部分空闲的连接线程保持在一个缓存区以备新进连接请求的时候使用,这尤其对那些使用短连接的应用程序来说可以极大的提高创建连接的效率。当我们通过 thread_cache_size设置了连接线程缓存池可以缓存的连接线程的大小之后,可以通过(Connections - Threads_created) /Connections * 100% 计算出连接线程缓存的命中率。注意,这里设置的是可以缓存的连接线程的数目,而不是内存空间的大小。thread_cache_size注意,这里设置的是可以缓存的连接线程的数目,而不是内存空间的大小。表缓存表缓存区主要用来缓存表文件的文件句柄信息,在MySQL5.1.3之前的版本通过 table_cache 参数设置,但从MySQL5.1.3开始改为 table_open_cache来设置其大小。当我们的客户端程序提交 Query 给 MySQL 的时候,MySQL 需要对 Query所涉及到的每一个表都取得一个表文件句柄信息,如果没有 Table Cache,那么 MySQL就不得不频繁的进行打开关闭文件操作,无疑会对系统性能产生一定的影响,Table Cache 正是为了解决这一问题而产生的。在有了 TableCache 之后,MySQL 每次需要获取某个表文件的句柄信息的时候,首先会到 Table Cache中查找是否存在空闲状态的表文件句柄。如果有,则取出直接使用,没有的话就只能进行打开文件操作获得文件句柄信息。在使用完之后,MySQL会将该文件句柄信息再放回 Table Cache池中,以供其他线程使用。注意,这里设置的是可以缓存的表文件句柄信息的数目,而不是内存空间的大小table_open_cache表定义信息缓存表定义信息缓存是从MySQL5.1.3 版本才开始引入的一个新的缓存区,用来存放表定义信息。当我们的 MySQL中使用了较多的表的时候,此缓存无疑会提高对表定义信息的访问效率。MySQL 提供了 table_definition_cache参数给我们设置可以缓存的表的数量。在 MySQL5.1.25 之前的版本中,默认值为128,从 MySQL5.1.25版本开始,则将默认值调整为 256 了,最大设置值为524288。注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。table_definition_cache注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。二进制日志缓冲区二进制日志缓冲区主要用来缓存由于各种数据变更操做所产生的Binary Log 信息。为了提高系统的性能,MySQL 并不是每次都是将二进制日志直接写入 Log File,而是先将信息写入Binlog Buffer 中,当满足某些特定的条件(如 sync_binlog参数设置)之后再一次写入 Log File 中。我们可以通过binlog_cache_size 来设置其可以使用的内存大小,同时通过 max_binlog_cache_size限制其最大大小(当单个事务过大的时候 MySQL 会申请更多的内存)。当所需内存大于 max_binlog_cache_size参数设置的时候,MySQL 会报错:“Multi-statement transaction required more than‘max_binlog_cache_size’ bytes of storage”。binlog_cache_sizeMyISAM索引缓存MyISAM 索引缓存将 MyISAM 表的索引信息缓存在内存中,以提高其访问性能。这个缓存可以说是影响 MyISAM 存储引擎性能的最重要因素之一了,通过 key_buffere_size 设置可以使用的最大内存空间key_buffer_sizeInnoDB 日志缓冲区这是 InnoDB存储引擎的事务日志所使用的缓冲区。类似于 Binlog Buffer,InnoDB 在写事务日志的时候,为了提高性能,也是先将信息写入Innofb Log Buffer 中,当满足 innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)之后,才会将日志写到文件(或者同步到磁盘)中。可以通过 innodb_log_buffer_size参数设置其可以使用的最大内存空间innodb_log_buffer_size针对redo logInnoDB 数据和索引缓存InnoDB BufferPool 对 InnoDB 存储引擎的作用类似于 Key Buffer Cache 对 MyISAM 存储引擎的影响,主要的不同在于InnoDB Buffer Pool 不仅仅缓存索引数据,还会缓存表的数据,而且完全按照数据文件中的数据快结构信息来缓存,这一点和Oracle SGA 中的 database buffer cache 非常类似。所以,InnoDB Buffer Pool 对 InnoDB存储引擎的性能影响之大就可想而知了。可以通过 (Innodb_buffer_pool_read_requests -Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%计算得到 InnoDB Buffer Pool 的命中率。innodb_buffer_pool_sizeInnoDB 字典信息缓存InnoDB字典信息缓存主要用来存放 InnoDB 存储引擎的字典信息以及一些 internal 的共享数据结构信息。所以其大小也与系统中所使用的InnoDB 存储引擎表的数量有较大关系。不过,如果我们通过 innodb_additional_mem_pool_size参数所设置的内存大小不够,InnoDB 会自动申请更多的内存,并在 MySQL 的 Error Log 中记录警告信息。innodb_additional_mem_pool_size这里所列举的各种共享内存,是我个人认为对 MySQL 性能有较大影响的集中主要的共享内存。实际上,除了这些共享内存之外,MySQL还存在很多其他的共享内存信息,如当同时请求连接过多的时候用来存放连接请求信息的back_log队列等。
总条数:756 到第
上滑加载中