Percona监控工具初探

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因: 一直找不到合适的MySQL监控工具,正好听同事无意中说起,Percona在2016年4月发布了一个监控套件,可以同时对多个MySQL、MongoDB实例进行监控 参考资料: https://www.percona.com/blog/2016/04/18/percona-monitoring-and-management/ https://www.percona.com/doc/percona-monitoring-and-management/index.html https://www.percona.com/doc/percona-monitoring-and-management/install.html 安装过程描述的非常详尽,参考此文档足以 环境 操作系统版本CentOS 6.7 MySQL版本为 MySQL 5.7 1. 安装 1.1 PMM Server 负责将收集到的数据存储、聚合和展现 假定安装在192.168.100.1上 1) docker percona/pmm-server:1.0.6 2) docker create \ -v /opt/prometheus/data \ -v /opt/consul-data \ -v /var/lib/mysql \ -v /var/lib/grafana \ --name pmm-data \ percona/pmm-server:1.0.6 /bin/true 3) $ docker run -d \ -p 80:80 \ --volumes-from pmm-data \ --name pmm-server \ --restart always \ percona/pmm-server:1.0.6 到此,docker已经启动,可以访问 ...

January 1, 2018 · 3 min

rtorrent初探--利用好你的云主机

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因: 有了云主机以后,我常常想能够用它来做什么,当然可以用来挂网站,然后还能做什么,我想到可以把一些下载任务(BT)直接放到云主机来做,经过调研我选择了rtorrent。 1. 简介 rTorrent为一款纯文本环境BT客户端,具有占用内存小、频宽利用率高、支持 utf-8 编码等功能,除了在终端机界面操作,也可以在第三方支持下透过浏览器界面操作本软件。开发者杰瑞·森德尔(Jari Sundell)的目标是“一个侧重于高性能的良好代码。”属于自由软件。 2. 安装 centos yum install rtorrent ubuntu apt-get install rtorrent 安装完成以后,需要手动创建一个配置文件,配置文件需放在 ~/.rtorrent.rc 样例 以下列出比较重要的一些 # Directory to manage temporary downloads to # 下载好的文件的保存路径 directory = ~/Downloads/torrents/rtorrent_temp/ # 其它可调参, 单位是KB upload_rate = 30 download_rate = 200 peer_exchange = yes # 监听目录,只要有后缀为.torrent的文件就自动开始下载 schedule = watch_directory,0,10,load_start=~/Downloads/torrents/rtorrent_watch/*.torrent 启动(可以任何目录下直接启动) rtorrent 重要的命令: ↑↓ 用于选择任务 ctrl + s 开始下载任务 ctrl + d 停止下载任务,再按一次,删除停止的下载任务 ctrl + q 退出rtorrent **重要: ** 最后 rtorrent 只能在当前窗口运行,关闭窗口会导致程序退出 要想让它一直运行,需要和screen 或者tmux 结合使用 ...

January 1, 2018 · 1 min

requests 库的另类用法(stream)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因: 同事让我帮他抓取一批URL,并获取对应URL的<title>标签中的文字,忽略对应URL网站的封禁问题,这个任务并不是一个特别麻烦的事情。然后实际跑起来,却发现流量打的很高,超过10Mb/s。 经过排查发现,是因为很多URL,实际是下载链接,会触发文件下载,这些URL对应的html中根本不会包含<title>标签,那么处理逻辑就很清晰了,先拿到headers,取出Content-Type,判断是否是 text/html,如果不是,则该Response的body体,就没有必要读取了。 查找requests的相应资料 By default, when you make a request, the body of the response is downloaded immediately. You can override this behaviour and defer downloading the response body until you access the Response.content attribute with the stream parameter: tarball_url = &#039;https://github.com/kennethreitz/requests/tarball/master&#039; r = requests.get(tarball_url, stream=True) At this point only the response headers have been downloaded and the connection remains open, hence allowing us to make content retrieval conditional: ...

January 1, 2018 · 1 min

算法题(6)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 题目: 已知一个矩阵 matrix = [ [&#039;A&#039;, &#039;P&#039;, &#039;H&#039;, &#039;S&#039;], [&#039;U&#039;, &#039;L&#039;, &#039;O&#039;, &#039;A&#039;], [&#039;O&#039;, &#039;M&#039;, &#039;L&#039;, &#039;K&#039;], [&#039;F&#039;, &#039;B&#039;, &#039;I&#039;, &#039;R&#039;], ] 在矩阵中查找多个字符串,字符串的数量可能很多 [&quot;LFK&quot;, &quot;HMM&quot;, &quot;RPOOI&quot;] 对于字符串"LFK",它由3个字符组成,‘L’、‘F’、‘K’ 这三个字符在矩阵中的位置分别为(1,1),(3,0),(2,3) 对于这个三个字符串分别返回 LFK True, [(1,1),(3,0),(2,3)] HMM 矩阵中的每个字符只能被使用一次,字符M在矩阵中只有一个,因此 HMM 无法找到 False, [] RPOOI True, [(3,3),(0,1),(1,2),(2,0),(3,2)] 分析 矩阵中的字符数量有限(全是大写字母),且每个字符只能被使用一次,由于待查的字符串数量很多,所以需要为查找建立索引 最终代码如下: # encoding=utf-8 from collections import defaultdict def get_position(matrix, str_list): # 初始化索引 dd = defaultdict(list) for i in range(len(matrix)): for j in range(len(matrix[i])): ch = matrix[i][j] dd[ch].append((i, j)) # deal res = [] for ss in str_list: print ss curr_dd = defaultdict(int) flag = True position_list = [] for ch in ss: curr_dd[ch] += 1 if curr_dd[ch] &lt;= len(dd[ch]): position_list.append(dd[ch][curr_dd[ch] - 1 ]) else: flag = False res.append((False, [])) break if flag: res.append((True, position_list)) return res if __name__ == &#039;__main__&#039;: matrix = [ [&#039;A&#039;, &#039;P&#039;, &#039;H&#039;, &#039;S&#039;], [&#039;U&#039;, &#039;L&#039;, &#039;O&#039;, &#039;A&#039;], [&#039;O&#039;, &#039;M&#039;, &#039;L&#039;, &#039;K&#039;], [&#039;F&#039;, &#039;B&#039;, &#039;I&#039;, &#039;R&#039;], ] str_list = [&quot;ISIS&quot;, &quot;ALLAHU&quot;] res = get_position(matrix, str_list) for item in res: print item

January 1, 2018 · 1 min

时间片计算

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc ###起因 要进行预约时间的计算,干脆做一个简单的模块专门用于时间片的计算,等时间有空了会传到pypi上 1. 时间片的合并 ll = [] dd = { &quot;start_time&quot;: &quot;20:00&quot;, &quot;end_time&quot;: &quot;22:00&quot; } ll.append(dd) dd = { &quot;start_time&quot;: &quot;10:00&quot;, &quot;end_time&quot;: &quot;12:00&quot; } ll.append(dd) dd = { &quot;start_time&quot;: &quot;14:00&quot;, &quot;end_time&quot;: &quot;18:00&quot; } ll.append(dd) dd = { &quot;start_time&quot;: &quot;15:00&quot;, &quot;end_time&quot;: &quot;17:00&quot; } ll.append(dd) dd = { &quot;start_time&quot;: &quot;11:00&quot;, &quot;end_time&quot;: &quot;15:00&quot; } ll.append(dd) dd = { &quot;start_time&quot;: &quot;18:00&quot;, &quot;end_time&quot;: &quot;19:00&quot; } ll.append(dd) res = TimeFrame.merge(ll) record = res[0] assert record[&#039;start_time&#039;] == &quot;10:00&quot; assert record[&#039;end_time&#039;] == &quot;19:00&quot; record = res[1] assert record[&#039;start_time&#039;] == &quot;20:00&quot; assert record[&#039;end_time&#039;] == &quot;22:00&quot; 2. 时间片相减 item_list1 = [] dd = { &quot;start_time&quot;: &quot;08:00&quot;, &quot;end_time&quot;: &quot;15:00&quot;, } item_list1.append(dd) item_list2 = [] dd = { &quot;start_time&quot;: &quot;09:00&quot;, &quot;end_time&quot;: &quot;10:00&quot;, } item_list2.append(dd) dd = { &quot;start_time&quot;: &quot;11:00&quot;, &quot;end_time&quot;: &quot;12:00&quot;, } item_list2.append(dd) res_list = TimeFrame.minus(item_list1, item_list2) record = res_list[0] assert record[&#039;start_time&#039;] == &quot;08:00&quot; assert record[&#039;end_time&#039;] == &quot;09:00&quot; record = res_list[1] assert record[&#039;start_time&#039;] == &quot;10:00&quot; assert record[&#039;end_time&#039;] == &quot;11:00&quot; record = res_list[2] assert record[&#039;start_time&#039;] == &quot;12:00&quot; assert record[&#039;end_time&#039;] == &quot;15:00&quot; 代码如下 time_frame.py ...

January 1, 2018 · 2 min

指定出口IP,发起HTTP请求

# -*- coding=utf-8 -*- import socket import requests true_socket = socket.socket ipbind=&#039;xxx.xxx.xxx.xxx&#039; def bound_socket(*a, **k): sock = true_socket(*a, **k) # 端口是0, 操作系统会自动选择可用的端口号 sock.bind((ipbind, 0)) return sock socket.socket = bound_socket r = requests.get(&#039;http://ip.cn/&#039;) print r.status_code

January 1, 2018 · 1 min

kafka查看队列的消费情况

kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --broker-info --group $group --topic $topic --zookeeper $zk_host:2181 0.9.0以后官方建议使用 kafka-consumer-groups.sh --new-consumer --bootstrap-server $broker:9092 --describe --group $topic

January 1, 2018 · 1 min

在一个Python脚本中加载2种不同版本的库

起因: 从ES集群A往ES集群B导数,然后比对2个ES的数据差异,逐个ID比对。由于ES集群A的版本是1.4.x,ES集群B的版本是5.3.x,所以无法使用同一个ES client包 1. 加载不同版本的client包 对比的过程是,取相同发布时间区间的文章ID,然后比对id的差异 伪码如下: es_A_ids = get_es_A_ids() es_B_ids = get_es_B_ids() diff_ids = es_A_ids - es_B_ids 可以想到的是在访问完集群A后重新加载elasticsearch 库 ## load elasticsearch==1.4.0 es_A_ids = get_es_A_ids() ## load elasticsearch==5.3.0 es_B_ids = get_es_B_ids() diff_ids = es_A_ids - es_B_ids 但是很有趣的是,elasticsearch在load完上一个版本以后,它的版本没有发生变化 2. 清理已经load 的module 经过查资料,我明确了这个问题,python的module,只会被load,有且一次,所以要保证不同版本的module被再次load,只能先clear 原先load的module ES的module都以elasticsearch开头,因此把它们都清理掉 for key in sys.modules.keys(): if key.startswith(&#039;elasticsearch&#039;): del sys.modules[key] 完整代码 import importlib import sys # use elasticsearch 5.x es_lib_path = &quot;/Users/woshiaotian/es_5x/lib/python2.7/site-packages&quot; # 注意要把es_lib_path放在sys.path 的首位,确保load module的时候,该目录下的ES库,能够被优先加载 sys.path.insert(0, es_lib_path) #print sys.path elasticsearch = importlib.import_module(&quot;elasticsearch&quot;) print elasticsearch sys.path.pop(0) for key in sys.modules.keys(): if key.startswith(&#039;elasticsearch&#039;): print key del sys.modules[key] # use elasticsearch 1.x es_lib_path = &quot;/Users/woshiaotian/es_1x/lib/python2.7/site-packages&quot; sys.path.insert(0, es_lib_path) elasticsearch = importlib.import_module(&quot;elasticsearch&quot;) print elasticsearch sys.path.pop(0) #print sys.path for key in sys.modules.keys(): if key.startswith(&#039;elasticsearch&#039;): print key del sys.modules[key] sys.modules This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail. ...

January 1, 2018 · 1 min

用grequests实现并发http请求

起因 要用http请求探测服务的有效性,多进程,多线程,感觉似乎没有必要,看看有没有协程的方案 1. 简单用法 grequests 利用 requests和gevent库,做了一个简单封装,使用起来非常方便 import grequests import time import requests urls = [ &#039;https://docs.python.org/2.7/library/index.html&#039;, &#039;https://docs.python.org/2.7/library/dl.html&#039;, &#039;http://www.iciba.com/partial&#039;, &#039;http://2489843.blog.51cto.com/2479843/1407808&#039;, &#039;http://blog.csdn.net/woshiaotian/article/details/61027814&#039;, &#039;https://docs.python.org/2.7/library/unix.html&#039;, &#039;http://2489843.blog.51cto.com/2479843/1386820&#039;, &#039;http://www.bazhuayu.com/tutorial/extract_loop_url.aspx?t=0&#039;, ] def method1(): t1 = time.time() for url in urls: res = requests.get(url) #print res.status_code t2 = time.time() print &#039;method1&#039;, t2 - t1 def method2(): tasks = [grequests.get(u) for u in urls] t1 = time.time() res = grequests.map(tasks, size=3) # print res t2 = time.time() print &#039;method2&#039;, t2 - t1 def method3(): tasks = [grequests.get(u) for u in urls] t1 = time.time() res = grequests.map(tasks, size=6) # print res t2 = time.time() if __name__ == &#039;__main__&#039;: method1() method2() method3() 运行结果如下: ...

January 1, 2018 · 1 min

wget bind ip 失败

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因: 我们的程序需要从文件服务器拉去文件(跨机房), 程序运行的机器有电信、联通、移动3线,3个IP 假定为 01_DX_IP, 01_LT_IP, 01_YD_IP 文件服务器也是电信、联通、移动3线,3个IP 02_DX_IP, 02_LT_IP, 02_YD_IP 其域名为myfile.com 使用wget拉去文件,为了保证出口带宽用的尽量上,绑定出口IP wget --bind-address=01_YD_IP -t 3 -T 120 --limit-rate=3M -S -O 1407856770354_858932.mp4 http://myfile.com/data10/sony/303/2014-08/12/1407856770354_858932.mp4 按照预先的想法,绑定了移动IP,正常DNS服务器会返回一个文件服务器的移动IP,速度应该不会太慢,事情情况下,下载速度不到100k 1. 排查: 1.1 观察文件下载连接 观察wget打印的日志,显示实际建立连接访问的是联通的IP Resolving myfile.com... 02_LT_IP, ... Connecting to myfile.com|02_LT_IP|:80... connected. HTTP request sent, awaiting response... ^C 使用lsof观察进程的连接情况 [xxx@c3n~]$ sudo lsof -p 133396 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME wget 133396 root cwd DIR 8,2 4096 59640871425 /datapool/log/inject/xxx.log wget 133396 root 6w REG 0,17 164815000 59756490241 /datapool/injectBase/1408203875738_777462.mp4 wget 133396 root 7u IPv4 1479434406 0t0 TCP 01_YD_IP:29657->02_LT_IP:http (ESTABLISHED) 注意这一行 TCP 01_YD_IP:29657->02_LT_IP:http (ESTABLISHED) 本地的bind address确实已经生效,已经绑定了移动IP, 但是文件服务器的IP地址却是联通IP, 那只能是DNS解析有问题了 ...

January 1, 2018 · 2 min