November 21, 2011
图解”How MySQL Replication Works”
"\u003cp\u003e示意图:\n\u003ca href=\"http://blog.haohtml.com/wp-content/uploads/2011/11/mysql-replication-master-slave.jpg\"\u003e\u003cimg src=\"http://blog.haohtml.com/wp-content/uploads/2011/11/mysql-replication-master-slave.jpg\" alt=\"\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e在使用MySQL的应用中,如果你的MySQL Server压力逐渐增大,在应用层优化已经到了一定瓶颈时,那么你应该首先考虑 \u003ca href=\"http://dev.mysql.com/doc/refman/5.0/en/replication.html\"\u003eMySQL_Replication\u003c/a\u003e。本文将利用图示的方式简单的描述出MySQL Replication是如何工作的。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e如何同步\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e主库将所有的更新操作,写入二进制日志。\u003c/li\u003e\n\u003cli\u003e从库运行”IO线程”(Slave IO Thread)读取主库的二进制日志。\u003c/li\u003e\n\u003cli\u003e从库运行”SQL线程”(Slave SQL Thread)执行IO线程(Slave IO Thread)读取的日志中的SQL,从而保持和主库的一致。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003e如何分配请求\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e目前,这部分需要在应用层实现。\u003c/li\u003e\n\u003cli\u003e执行更新SQL(UPDATE,INSERT,DELETE)时,请求主库。\u003c/li\u003e\n\u003cli\u003e执行查询SQL(SELECT)时,请求从库。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e所以,当你的应用(Application)SELECT请求所占的比率越大,那么Relication就会越有效。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e相关教程:\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eMySQL传输二进制日志原理:\u003c/p\u003e"
November 21, 2011
MySQL传输二进制日志原理
"\u003cp\u003e摘自:\u003c/p\u003e\n\u003cp\u003eMySQL Replication可以很方便的用来做应用的读扩展,也可以帮MySQL实现一定程度的HA方案。MySQL通过\u003ca href=\"http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/\"\u003e向备库传送二进制日志来实现Replication\u003c/a\u003e,本文将通过二进制日志相关源代码的主要接口来解释:“\u003cstrong\u003eMySQL如何传输二进制日志,是主库推,还是备库拉?MySQL日志传输的实时性如何?\u003c/strong\u003e”。\u003c/p\u003e\n\u003cp\u003e在MySQL Replication结构中,备库端初次通过\u003ca href=\"http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html\"\u003eCHANGE MASTER TO\u003c/a\u003e完成Replication配置,再使用start slave命令开始复制。更细致的,备库通过IO Thread向主库发起读取binlog的请求(COM_BINLOG_DUMP命令),主库收到COM_BINLOG_DUMP请求后,使用单独线程(dump thread)不断向备库IO Thread发送Binlog。示意图:\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://blog.haohtml.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg\"\u003e\u003cimg src=\"https://blogstatic.haohtml.com//uploads/2023/09/how_mysql_send_binary_log.jpg\" alt=\"\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e在主库端一旦有新的日志产生后,立刻会发送一次广播,dump线程在收到广播后,则会读取二进制日志并通过网络向备库传输日志,所以这是一个主库向备库不断推送的过程;\u003c/p\u003e\n\u003cp\u003e新日志在产生后,只需一次广播和网络就会立刻(\u0026lt;1ms)向发送到备库,如果主备之间网络较好的话(例 …\u003c/p\u003e"
November 21, 2011
varnish中vcl_recv子程序actions 动作
"\u003cp\u003e\u003cstrong\u003e主要有以下动作\u003c/strong\u003e\npass \\当一个请求被pass后,这个请求将通过varnish转发到后端服务器,但是它不会被缓存。pass可以放在vcl_recv 和 vcl_fetch中。\nlookup \\当一个请求在vcl_recv中被lookup后,varnish将从缓存中提取数据,如果缓存中没有数据,将被设置为pass,不能在 vcl_fetch中设置lookup。\npipe \\pipe和 pass相似,都要访问后端服务器,不过当进入pipe 模式后,在此连接未关闭前,后续的所有请求都发到后端服务器(这句是我自己理解后简化的,有能力的朋友可以看看官方文档,给我提修改建议) 。\ndeliver \\请求的目标被缓存,然后发送给客户端\nesi \\ESI-process the fetched document(我理解的就是vcl 中包换一段 html代码)\u003c/p\u003e"
November 21, 2011
varnishstat 参数分析
"\u003cp\u003eHitrate ratio由三个数字组成,第一个数字范围0-10,第二个数字范围0-100,第三个数字范围0-1000。\u003c/p\u003e\n\u003cp\u003e分别表示过去N秒内的Hitrate avg。上图由于我是刚打开varnishstat,因此三个数字都是4,表示过去4秒内的平均hitrate,如果打开的时间足够长,以上三个数字就会逐渐变成\u003cstrong\u003e10,100,1000\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003eHitrate avg里的内容是命中率,需要乘以100转换成百分比,例如上图表示命中率为99.23%\u003c/p\u003e\n\u003cp\u003e接着往下看,三列数据分别表示实时数据,每秒平均值,自启动以来每秒平均值。有些参数是没有后两列的,这是因为这些值都有固定变动范围,例如N work threads,只会在0到最大值(我设的是200)之间变动,搞每秒平均值意义不大(我猜)。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e以下指标需要重点关注一下:\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eClient connections accepted: (每秒处理连接数)。\nClient requests received:经验表明connection:request=1:10左右时比较理想,比这个数大很多或者小很多都是不好的。代表到目前为止,浏览器向反向代理服务器发送的HTTP请求累积 …\u003c/p\u003e"
November 21, 2011
varnishncsa(以 NCSA 的格式显示日志)
"\u003cp\u003e\u003cstrong\u003e●varnishncsa(以 NCSA 的格式显示日志)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eAuthor: Dag-Erling Sm?rgrav\u003c/p\u003e\n\u003cp\u003eDate: 2010-05-31\u003c/p\u003e\n\u003cp\u003eVersion: 1.0\u003c/p\u003e\n\u003cp\u003eManual section: 1\u003c/p\u003e\n\u003cp\u003eDisplay varnish logs in apache/NCSA combined log format\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSYNOPSIS\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003evarnishncsa [-a] [-b] [-C] [-c] [-D] [-d] [-f] [-I regex] [-i tag]\u003c/p\u003e\n\u003cp\u003e[-n varnish_name] [-P file] [-r file] [-V] [-w file] [-X regex] [-x tag]\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eDESCRIPTION\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eVarnishncsa 工具读取共享内存的日志,然后以 apache/NCSA 的格式显示出来。下 面的选项可以用。\u003c/p\u003e\n\u003cp\u003e-a 当把日志写到文件里时,使用附加,而不是覆盖。\u003c/p\u003e\n\u003cp\u003e-b 只显示 varnishd 和后端服务器的日志。\u003c/p\u003e\n\u003cp\u003e-C 匹配正则表达式的时候,忽略大小写差异。\u003c/p\u003e\n\u003cp\u003e-c 只显示 varnishd 和客户端的日志。\u003c/p\u003e\n\u003cp\u003e-D 以进程方式运行\u003c/p\u003e\n\u003cp\u003e-d 在 …\u003c/p\u003e"
November 21, 2011
Misbehaving servers(服务器停止运转)
"\u003cp\u003eVarnish的一个关键特色就是它有能力防御 web和应用服务器宕机。\n\u003cstrong\u003eGrace mode\u003c/strong\u003e\n当几个客户端请求同一个页面的时候,varnish只发送一个请求到后端服务器,然后让那个其他几个请求挂起等待返回结果,返回结果后,复制请求的结果发送给客户端。\n如果您的服务每秒有数千万的点击率,那么这个队列是庞大的,没有用户喜欢等待服务器响应。为了使用过期的 cache 给用户提供服务,我们需要增加他们的 TTL,保存所有cache 中的内容在 TTL过期以后30 分钟内不删除,使用以下VCL:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esub vcl_fetch {\n set beresp.grace = 30m;\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eVarnish 还不会使用过期的目标给用户提供服务,所以我们需要配置以下代码,在cache过期后的15 秒内,使用旧的内容提供服务:\n\u003c/code\u003e\u003c/pre\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esub vcl_recv {\n set req.grace = 15s;\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e你会考虑为什么要多保存过去的内容 30 分钟?当然,如果你使用了健康检查,你可以通过健康状态设置保存的时间:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eif (! req.backend.healthy) {\n set req.grace …\u003c/code\u003e\u003c/pre\u003e"
November 21, 2011
varnish中的Health checks(健康检查)
"\u003cp\u003e让我们设置一个 director和两个后端,然后加上健康检查:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebackend server1 {\n .host = \u0026#34;server1.example.com\u0026#34;;\n .probe = {\n .url = \u0026#34;/\u0026#34;;\n .interval = 5s;\n .timeout = 1 s;\n .window = 5;\n .threshold = 3;\n }\n }\nbackend server2 {\n .host = \u0026#34;server2.example.com\u0026#34;;\n .probe = {\n .url = \u0026#34;/\u0026#34;;\n .interval = 5s;\n .timeout = 1 s;\n .window = 5;\n .threshold = 3;\n }\n }\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这些新的就是探针,varnish将检查通过探针检查每个后端服务器是 …\u003c/p\u003e"
November 21, 2011
varnish中的Directors
"\u003cp\u003e您可以把多台 backends 聚合成一个组,这些组被叫做 directors。这样可以增强性能和弹力。您可以定义多个 backends和多个 group在同一个directors。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebackend server1 {\n .host = \u0026#34;192.168.0.10\u0026#34;;\n}\nbackend server2{\n .host = \u0026#34;192.168.0.10\u0026#34;;\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e现在我们创建一个 director:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003edirector example_director round-robin {\n{\n .backend = server1;\n}\n# server2\n{\n .backend = server2;\n}\n# foo\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这个 director 是一个循环的 director。它的含义就是 director 使用循环的方式把backends分给请求。\n但是如果您的一个服务器宕了?varnish 能否指导所有的请求到健康的后端?当然可以,这就是健康检查在起作用了。\u003c/p\u003e"
November 21, 2011
varnish中advanced backend configuration (后端服务高级配置)
"\u003cp\u003e在某些时刻您需要 varnish 从多台服务器上缓存数据。您可能想要 varnish 映射所有的URL 到一个单独的主机或者不到这个主机。这里很多选项。\n我们需要引进一个 java程序进出php的web站点。假如我们的java程序使用的 URL开始于/JAVA/\u003c/p\u003e\n\u003cp\u003e我们让它运行在8000端口,现在让我们看看默认的default.vcl:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebackend default {\n .host = \u0026#34;127.0.0.1\u0026#34;;\n .port = \u0026#34;8080\u0026#34;;\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e我们添加一个新的 backend:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebackend java {\n .host = \u0026#34;127.0.0.1\u0026#34;;\n .port = \u0026#34;8000\u0026#34;;\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e现在我们需要告诉特殊的URL 被发送到哪里:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esub vcl_recv {\n if (req.url ~ \u0026#34;^/java/\u0026#34;) {\n set req.backend = java;\n } else {\n set req.backend …\u003c/code\u003e\u003c/pre\u003e"
November 21, 2011
Achiveving a high hitrate(提高缓存命中率)-varnish篇
"\u003cp\u003e现在 varnish 已经正常运行了,您可以通过 varnish 访问到您的 web 应用程序。如果您的 web 程序在设计时候没有考虑到加速器的架构,那么您可能有必要修改您的应用程序或者varnish配置文件,来提高varnish的命中率。\n既然这样,您就需要一个工具用来观察您和web服务器之间HTTP头信息。服务器端您可以轻松的使用varnish 的工具,比如varnishlog和 varnishtop,但是客户端的工具需要您自己去准备,下面是我经常使用的工具。\n\u003cstrong\u003eVarnistop\u003c/strong\u003e\n您可以使用varnishtop 确定哪些URL经常命中后端。 Varnishtop –i txurl 就是一个基本的命令。您可以通过阅读“Statistics”了解其他示例。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eVarnishlog\u003c/strong\u003e\n当您需要鉴定哪个 URL 被频繁的发送到后端服务器,您可以通过varnishlog对请求做一个全面的分析。 varnishlog –c –o /foo/bar 这个命令将告诉您所有(-o)包含”/football/bar”字段来自客户端(-c)的请求。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eLwp-request\u003c/strong\u003e\nLwp-request是 www …\u003c/p\u003e"
November 21, 2011
varnish中的Statistics(统计 varnish相关数据)-Varnishtop ,Varnishhist ,Varnishsizes ,Varnishstat
"\u003cp\u003e现在您的varnish已经正常运行,我们来看一下varnish在做什么,这里有些工具可以帮助您做到。\n\u003cstrong\u003eVarnishtop\u003c/strong\u003e\nVarnishtop工具读取共享内存的日志,然后连续不断的显示和更新大部分普通日志。\n适当的过滤使用 –I,-i,-X 和-x 选项,它可以按照您的要求显示请求的内容,客户端,浏览器等其他日志里的信息。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003evarnishtop -i rxurl \\您可以看到客户端请求的 url次数。\nVarnishtop -i txurl \\您可以看到请求后端服务器的url次数。\nVarnishtop -i Rxheader –I Accept-Encoding \\可以看见接收到的头信息中有有多少次包含Accept-Encoding。\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003eVarnishhist\u003c/strong\u003e\nVarnishhist工具读取varnishd的共享内存段日志,生成一个连续更新的柱状图,显示最后 N 个请求的处理情况。这个 N 的值是终端的纵坐标的高度,横坐标代表的是对数,如果缓存命中就标记“|”,如果缓存没有命中就标记上“#”符号。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eVarnishsizes\u003c/strong\u003e\nVarnishsizes 和varnishhist相似,除 …\u003c/p\u003e"
November 21, 2011
Varnish Configuration Language – VCL (varnish 配置 语言-VCL)
"\u003cp\u003e官方手册:\u003c/p\u003e\n\u003cp\u003e** **Varnish 有一个很棒的配置系统,大部分其他的系统使用配置指令,让您打开或者关闭一些开关。 Varnish使用区域配置语言,这种语言叫做“VCL”(varnish configuration language),在执行vcl时,varnish 就把VCL转换成二进制代码。\n** **VCL 文件被分为多个子程序,不同的子程序在不同的时间里执行,比如一个子程序在接到请求时执行,另一个子程序在接收到后端服务器传送的文件时执行。\nvarnish 将在不同阶段执行它的子程序代码,因为它的代码是一行一行执行的,不存在优先级问题。随时可以调用这个子程序中的功能并且当他执行完成后就退出。\u003c/p\u003e\n\u003cp\u003e** **如果到最后您也没有调用您的子进程中的功能,varnish 将执行一些内建的 VCL代码,这些代码就是default.vcl 中被注释的代码.\u003c/p\u003e\n\u003cp\u003e** 99%的几率您需要改变vcl_recv 和 vcl_fetch 这两个子进程。**\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003evcl_recv\u003c/strong\u003e\n** **vcl_recv(当然,我们在字符集上有点不足,应为它是unix)在请求的开始被调用,在接收、解析 …\u003c/p\u003e"
November 21, 2011
PutVarnish on port 80(使varnish工作在 80 端口上)
"\u003cp\u003e\u003cstrong\u003ePutVarnish on port 80(使 varnish工作在 80 端口上)\u003c/strong\u003e\n如果您的程序正常运行,没有问题,我们就可以把varnish调整到80端口运行。先关闭vernish\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003epkill varnishd\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e然后停止您的 web服务器,修改web服务器配置,把 web服务器修改成监听8080端口,然后修改varnish 的default.vcl和改变默认的后端服务器端口为8080.\n先启动您的web服务器,然后在启动varnish:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003evarnishd -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e我们取消了-a 选项,这样varnish将监控默认端口,启动后,检查您的 web程序是否正常。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e相关教程:\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003evarnish中Varnishlog命令解析:\u003c/p\u003e\n\u003cp\u003elinux下varnish配置及使用教程:\u003c/p\u003e\n\u003cp\u003eVarnish Configuration Language – VCL (varnish 配置 语言-VCL):\u003c/p\u003e\n\u003cp\u003evarnish中的Statistics(统计 varnish相关数 …\u003c/p\u003e"
November 21, 2011
varnish中Varnishlog命令解析
"\u003cp\u003eVarnish一个真正的特点就是它如何记录数据的。使用内存段代替普通的日志文件,当内存段使用完以后,又从头开始,覆盖最旧的记录。这样就可以非常快的记录数据,并且不需要磁盘空间。缺点就是您没有把数据写到磁盘上,可能会消失。 (varnish也支持将数据写到硬盘的文件上,看您如何选择)\nVarnishlog 这个程序可以查看 varnish 记录了哪些数据。Varnishlog 给您生成原始的日志,包括所有的事件。我一会给您演示。\n在运行了varnish的终端窗口上,运行varnishlog这个命令。\n您可以看见如下显示\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e#./varnishlog\n0 CLI – Rd ping\n0 CLI – Wr 200 PONG 1277172542 1.0\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e这是检查varnish的主进程是否正常,如果看见这就说明一切OK.\u003c/p\u003e\n\u003cp\u003e现在您去浏览器通过 varnish 重新访问您的 web程序,您将看到如下信息:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e11 SessionOpen c 127.0.0.1 58912 0.0.0.0:8080\n11 ReqStart c 127.0.0.1 58912 595005213\n11 …\u003c/code\u003e\u003c/pre\u003e"
November 20, 2011
Troubleshooting varnish(varnish排错方法)
"\u003cp\u003e1.有时候 varnish 会出错,为了使您知道该检查哪里,您可以检查 varnishlog,/var/log/syslog/,var/log/messages 这里可以发现一些信息,知道varnish怎么了。\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e2.When varnish won’t start\n有些时候,varnish 不能启动。这里有很多 varnish不能启动的原因,通常我们可以观看/dev/null的权限和是否其他软件占用了端口。\n使用debug模式启动 varnish,然后观看发生了什么:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003evarnishd -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:8080 –d\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e提示-d 选项,它将给您更多的信息关于接下来发生了什么。让我们看看如果其他程序暂用了varnish 的端口,它将显示什么:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# varnishd -n foo -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000\n-a …\u003c/code\u003e\u003c/pre\u003e"