Tech

Hadoop(Pig)统计IP地理位置

很常见的分析需求:日志中记录有访客IP(国内),现在要根据IP地址得出访客的地理位置,精确到市县一级,数据量平均是每天15G,需要统计日、周、月的结果。 最后的实现方式是,先找到IP地理位置数据库,包含每个ip段对应的地址:1.1.0.0,1.1.0.255,福建省然后把它转成具体每个IP对应的地址,即:1.1.0.1,福建省。这样在Pig中用JOIN的方式,就可以获得这个IP实际对应的地址了。 IP Database 12年成立的中国广告协会互动网络分会IP地理信息标准委员会(简称IPB)已经发布了IP地理信息标准库,委员会成员和大广告公司都有一份。也可以下载全球城市ip库,取其中CN部分: 文件信息:cn.csv 大小:1.26MB 有效时间:永久 读取这个文件,把ip转成数字,起止ip的差,就是这个ip段所包含的主机数,用range函数生成,主要的python代码如下:

处理结果会保存在out.csv文件中,中国地区总共有3亿个IP,生成的文件是7.9G,gz默认压缩后是900MB左右,按Map需求进行分割。 Pig Latin LOAD保存在hdfs中的日志文件(*.log.gz)和IP数据库(ip*.tar.gz),將日志文件中的访客IP转成数字,用JOIN方法组合,再做GROUP和COUNT的操作,就可以得出该地区的访客数了:

耗时44分33秒,统计出一周的结果: (北京市,32174022) (保定市,4244694) (邯郸市,1062551) Job Name: PigLatin:ip.pig Job-ACLs: All users are allowed Job Setup: Successful Status: Succeeded Finished in: 44mins, 33sec Job Cleanup: Successful Afterword 之前尝试做一个Pig的UDF,用{IP : CITY}形式的字典来做IP到城市的匹配,但JAVA函数大小有限制,而且用UDF会影响性能,所以没有采用。如果是自己写REDUCE来支持类似传统SQL中JOIN BETWEEN的方法,就不需要生成这个3亿多条记录的文件了。以上是在一个很小的测试Hadoop架构中进行的处理,理论上在实际生产环境可以处理得更快。

Continue Reading
Python Tech

ajenti的安装及插件制作

ajenti是Web方式的服务器管理平台,包含一系列常用运维工具,例如文件操作、服务管理、流量/磁盘空间实时监控等。这些工具本身倒是没什么亮点,我自己都写过。使用ajenti主要因为它是Python写的,修改扩展非常简单,我给它加了几个插件,省掉许多以前需要ssh连服务器进行操作。其次是它的界面交互做得不错,非专业人员也能使用,如果以后有多人管理的需求也能用上。本文分享安装和插件制作的步骤。 Install ajenti支持Ubuntu、Debian、REHL、CentOS、FreeBSD这5种Linux发行版,我是在两台Ubuntu和一台FreeBSD上安装的,流程都很简单,以Ubuntu为例:

Continue Reading
Python Tech

Python的dict转object

项目数据库是mongoDB,用pymongo进行find操作,查询结果是一串dict。现在要把查询结果用xlwt导出为csv文件,例如有一条数据如下:

要得到domain的值,是用row[‘domain’],但我希望能用对象的访问形式,例如row.domain来获取(严格来说这篇文章的标题有歧义,我真正的需求是改变dict的访问形式,而且Python中一切都是对象,object也是dict的基类。)

Continue Reading
Tech

用NodeJS实现APNS

APNS(Apple Push Notification service)可以给ios设备推送通知,直观表述就是当某个app在后台运行时,能弹出提示消息。相比Android来,只有这一套方案所以少了很多调研成本。标题写NodeJS,只是因为我们的生产环境是NodeJS,我也用其他语言调过,测试的库是这三个:node-apns(NodeJS) / PyAPNs(Python) / apns(Ruby)。本文的重点不是针对代码(因为确实没什么代码量),而是描述如何在Apple开发者中心请求证书、生成PEM文件、读取PEM文件和证书对APNs的沙盒发送请求,设备接收到Notification后进行处理这一系列流程的入门文章。 Tips & Preparations APNs整套系统的原理文档中写得很详细,此处不赘述。只引用下图作为说明。 NodeJS要实现的是Provider(以下称服务)部分。 1. 需要申请Apple开发者帐号,准备一台真实设备。模拟器没有Device Token,不能测试APNS; 2. 收到提醒时,如果程序在前台打开会看不到提醒; 3. 如果连续推送内容相同的提醒会失败。

Continue Reading
Tech

MongoDB无法启动的解决方法

遇到MongoDB突然无法启动,第一反应是删除mongod.lock。这个文件在MongoDB的数据库目录下,默认是/data/db。这是最常见的问题了,产生原因是MongoDB没有正常结束(比如被kill -9杀掉或是其他意外情况导致中断)。 还一些其他情况会导致MongoDB无法启动。本文讨论的无法启动,是指:使用/etc/init.d/mongodb start或是sudo service mongdb start,提示mongodb start/running,但查看status仍然是stop/waiting。 service SERVERNAME status有可能误报,先确认MongoDB的实际状态。主要是ps axu|grep mongod查看是否有相关进程,打开links或是直接用浏览器访问127.0.0.1:28017,看不到MongoDB的信息说明没有启动。

Continue Reading
Python Tech

Django+又拍云+file-uploader快速实现批量上传

最近做的工作都和Django没什么关系,或者都是比较底层的算法,不方便share,所以分享一些老东西。 之前写过Django用uploadify实现图片批量上传,从反馈来看,问题很多。现在uploadify更新到了3.2版,仍然是用swf来实现批量上传,代码还是老样子一团糟。作为替代换成了file-uploader,虽然是multipart/form-data来实现批量上传,不如swf的方式通用。但我不需要兼容老版本浏览器,做的都是富js应用,更看重代码的可扩展性,file-uploader更合适。 再说又拍云,最开始是在UEditor里做了一个图片上传到又拍云的功能,自动生成缩略图和水印的功能节省了不少开发时间。后来遇到一些不需要富文本编辑器的场合,就把这部分功能抽了出来,代码量非常小,是我至今用过的最快也是最通用的图片批量上传方案。

Continue Reading
Python Tech

Avro用php请求python服务的例子

Avro是Hadoop项目之一。主要用来支持数据密集型应用,它定义了一种数据格式并在多种编程语言中支持这种格式。我们最主要是用来操作Cassandra,其次是以RPC的方式,实现语言之间的相互调用。 架构中有很多轻量的python脚本,比如,PHP接收到一个URL,需要调用Python脚本,去取这个URL的标题,然后返回。之前是用cli从命令行直接调用,效果不是很好,经常会卡死,有时还会占用PHP的端口导致php-fpm无法启动。这种场景又不能用RabbitMQ之类的异步处理。所以用Avro实现了一个简单的调用,跑了一个多月,目前一切正常,现在分享相关代码。 原理:PHP和Python使用同一个Schema,用Python的HTTPServer做一个http服务,PHP端将数据以avro/binary的方式编码,传给Python,Python端以同样的方法解码,获得传递的数据,进行处理后返回结果给PHP端。 需要用到avro官方提供的Python模块和PHP库。用pip安装avro时,需要先安装libsnappy。

Continue Reading
Python Tech

Ubuntu安装Cassandra并配置多节点

Cassandra是一套分布式数据库,设计思想比较接近Big Table和Amazon Dynamo。从08年开源到现在,经历了Digg的悲剧,Twitter的调教,最新版本1.1版,已经开始进入平稳发展期了。我们现在有很多结构简单但读写频繁的数据,基于性能(跑分王)扩展性(多Cluster)等方面的考虑,用Cassandra搭了一个ring,目前为止运作正常。本文介绍在Ubuntu中安装Cassandra,用两台服务器做为两个节点搭建出一个ring,最后用pycassa把MySQL中的数据导入Cassandra。 Install 在Ubuntu中用官方提供的Debian源安装,版本是1.1.4,进行以下操作前建议先切换到root帐号。 在/etc/apt/source.list中增加cassandra的源: deb http://www.apache.org/dist/cassandra/debian 11x main deb-src http://www.apache.org/dist/cassandra/debian 11x main

Continue Reading
Python Tech

API设计参考(附Python SDK例子)

在Web应用中,API(Application Programming Interface 应用程序接口)的使用频率非常高,Google、推特、脸书,每天都会处理几十亿次的API调用请求。API接口一旦公布很难修改,所以设计要慎之又慎。本文主要归纳几种流行的Web应用API接口,总结它们的特点,供需要设计API的开发者作为参考。顺带介绍编写Python SDK调用API的技巧,最后是用作为例子的多说Python SDK。 几个常见的API对比 右图是ProgrammableWeb中最流行的几种API的整理: 支持协议:REST实质上是一种架构,ProgrammableWeb标注为协议(Protocols),专指利用URI直接访问资源的方式,所以协议上标明是REST并不代表它的URI形式也符合REST。如图所示,除了Youtube,其他几种API都采用了REST架构,甚至只提供Gdata的Youtube,都有开发者用Ruby给它加了一个REST的外壳。所以如果是一个新项目,API从一开始就采用REST架构比较好。 数据格式:所有API都支持XML。FB标注的是只支持XML,但根据之前开发的经验,请求FB的Graph数据返回的也是JSON,只有Twillo是只提供XML格式。JSON格式更简单,缺点是失去了命名空间等高级特征,而且不像XML有很多现成的开发工具。但“开发人员友好性”是API首要考虑的问题,能两种格式都能支持当然会更好,如果开发时间有限,综合来看可以选择先支持JSON。

Continue Reading
Python Tech

用rsyslog处理日志

之前是用mysql数据库来保存用户的访问日志,现在已经超过2亿了,速度非常慢,还分了三张表,要换一种记录日志的方式。现在暂时没有时间做数据挖掘,要做的只是把日志先存起来,所以直接用linux自带的rsyslog来做。用户访问时,以UDP的方式,将访问信息封装成JSON发到rsyslog的端口,rsyslog会以文本的方式直接记录下来。以后就可以用syslog-ng之类的工具写到mongo或其他数据库。 修改配置文件 新建一个配置文件: $ sudo vi /etc/rsyslog.d/00-dmyz.conf 默认的日志格式是日期:主机:信息(datetime, host, msg),现在只需要保存msg,host和datetime之类都写在的msg里,以日期作为文件名来存放日志:

然后修改 /etc/rsyslog.conf 打开UDP端口用来接收日志:

写入数据 python提供了socket,可以先用以下列方式测试写入是否正常:

如果一切正常,在/var/log/ 目录下会生成以当前日期作为文件名的.log文件,如果出错,最有可能是权限问题。还有,如果把生成的文件删除了,需要重启一次rsyslog服务,它才会重新生成。 以下是按天从mysql读出日志数据,发送到UDP 514端口的Python代码:

效果是,现在每天近千万的PV,生成的日志文件是1G左右,用bzip2压缩后只有100多MB,需要统计今天的访问量用wc命令就可以了。

Continue Reading