2018年7月

前言
实际上属于一种代码混淆/加密的技术,大家知道python的源文件放在那里,大家是都可以看的,不像C语言编译出来可以拿编译后的东西去运行,所以就出现了这种需求。原理相当于将python编译成c,然后再转成.so文件

.so文件为动态连结库,可以在程序运行时动态链接,类似于windows的dll文件。

在网上搜了一下,常用的有2种方法:

通过gcc(make)来操作
使用python来操作
准备工作
在目录下创建__init__.py和hello.py
hello.py 内容为:
def hello():

print "hello"

使用python来操作
安装所需库CPython,命令如下:
pip install cython
创建文件setup.py,内容如下:
from distutils.core import setup
from Cython.Build import cythonize
setup(

ext_modules = cythonize("hello.py")

)
执行setup.py文件
python setup.py build_ext --inplace
在当前目录下就生成了和当前目录同名的一个目录,进入目录即可看见so文件,打开so文件可见一些乱码,达到了加密的目的
使用gcc来编译
编译成c文件,完成后目录下多了hello.c
cython hello.py
编译成hello.o, 完成后目录下多了hello.o
gcc -c -fPIC -I/usr/include/python2.7/ hello.c
编译成so文件
gcc -undefined dynamic_lookup -shared hello.o -o hello.so
部分博客写的命令没有加-undefined dynamic_lookup的参数,会报错,提示
Undefined symbols for architecture x86_64
参考https://github.com/cloudwu/skynet_sample/issues/9 加上那个参数就好了

也有说加-lstdc++参数使用c++标准库就可以的,但是我尝试了不成功,依然报同样的错误
gcc -lstdc++ -v -shared hello.o -o hello.so
验证
在so文件目录下,进入python终端,然后尝试使用一下这个模块就可以了,如下:

from hello import hello
hello()
hello

pip代理安装包 pip install xxx -i https://pypi.douban.com/simple

font_path : string #字体路径,需要展现什么字体就把该字体路径+后缀名写上,如:font_path = '黑体.ttf'

width : int (default=400) #输出的画布宽度,默认为400像素

height : int (default=200) #输出的画布高度,默认为200像素

prefer_horizontal : float (default=0.90) #词语水平方向排版出现的频率,默认 0.9 (所以词语垂直方向排版出现频率为 0.1 )

mask : nd-array or None (default=None) #如果参数为空,则使用二维遮罩绘制词云。如果 mask 非空,设置的宽高值将被忽略,遮罩形状被 mask 取代。除全白(#FFFFFF)的部分将不会绘制,其余部分会用于绘制词云。如:bg_pic = imread('读取一张图片.png'),背景图片的画布一定要设置为白色(#FFFFFF),然后显示的形状为不是白色的其他颜色。可以用ps工具将自己要显示的形状复制到一个纯白色的画布上再保存,就ok了。

scale : float (default=1) #按照比例进行放大画布,如设置为1.5,则长和宽都是原来画布的1.5倍

min_font_size : int (default=4) #显示的最小的字体大小

font_step : int (default=1) #字体步长,如果步长大于1,会加快运算但是可能导致结果出现较大的误差

max_words : number (default=200) #要显示的词的最大个数

stopwords : set of strings or None #设置需要屏蔽的词,如果为空,则使用内置的STOPWORDS

background_color : color value (default=”black”) #背景颜色,如background_color='white',背景颜色为白色

max_font_size : int or None (default=None) #显示的最大的字体大小

mode : string (default=”RGB”) #当参数为“RGBA”并且background_color不为空时,背景为透明

relative_scaling : float (default=.5) #词频和字体大小的关联性

color_func : callable, default=None #生成新颜色的函数,如果为空,则使用 self.color_func

regexp : string or None (optional) #使用正则表达式分隔输入的文本

collocations : bool, default=True #是否包括两个词的搭配

colormap : string or matplotlib colormap, default=”viridis” #给每个单词随机分配颜色,若指定color_func,则忽略该方法

random_state : int or None #为每个单词返回一个PIL颜色

fit_words(frequencies) #根据词频生成词云
generate(text) #根据文本生成词云
generate_from_frequencies(frequencies[, ...]) #根据词频生成词云
generate_from_text(text) #根据文本生成词云
process_text(text) #将长文本分词并去除屏蔽词(此处指英语,中文分词还是需要自己用别的库先行实现,使用上面的 fit_words(frequencies) )
recolor([random_state, color_func, colormap]) #对现有输出重新着色。重新上色会比重新生成整个词云快很多
to_array() #转化为 numpy array
to_file(filename) #输出到文件

HDFS是一个不错的分布式文件系统,它有很多的优点,但也存在有一些缺点。目前而言,它在以下几个方面就效率不佳:
 

  1. 低延时访问

  HDFS不太适合于那些要求低延时(数十毫秒)访问的应用程序,因为HDFS是设计用于大吞吐量数据的,这是以一定延时为代价的。HDFS是单Master的,所有的对文件的请求都要经过它,当请求多时,肯定会有延时。当前,对于那些有低延时要求的应用程序,HBase是一个更好的选择。现在HBase的版本是0.20,相对于以前的版本,在性能上有了很大的提升,它的口号就是goes real time。
  使用缓存或多master设计可以降低client的数据请求压力,以减少延时。还有就是对HDFS系统内部的修改,这就得权衡大吞吐量与低延时了,HDFS不是万能的银弹。
  

  1. 大量小文件

   因为Namenode把文件系统的元数据放置在内存中,所以文件系统所能容纳的文件数目是由Namenode的内存大小来决定。一般来说,每一个文件、 文件夹和Block需要占据150字节左右的空间,所以,如果你有100万个文件,每一个占据一个Block,你就至少需要300MB内存。当前来说,数 百万的文件还是可行的,当扩展到数十亿时,对于当前的硬件水平来说就没法实现了。还有一个问题就 是,因为Map task的数量是由splits来决定的,所以用MR处理大量的小文件时,就会产生过多的Map task,线程管理开销将会增加作业时间。举个例子,处理10000M的文件,若每个split为1M,那就会有10000个Map tasks,会有很大的线程开销;若每个split为100M,则只有100个Map tasks,每个Map task将会有更多的事情做,而线程的管理开销也将减小很多。
  要想让HDFS能处理好小文件,有不少方法:
  1、利用SequenceFile、MapFile、Har等方式归档小文件,这个方法的原理就是把小文件归档起来管理,HBase就是基于此的。对于这种方法,如果想找回原来的小文件内容,那就必须得知道与归档文件的映射关系。
  2、横向扩展,一个Hadoop集群能管理的小文件有限,那就把几个Hadoop集群拖在一个虚拟服务器后面,形成一个大的Hadoop集群。google也是这么干过的。
  3、多Master设计,这个作用显而易见了。正在研发中的GFS II也要改为分布式多Master设计,还支持Master的Failover,而且Block大小改为1M,有意要调优处理小文件啊。
附带个Alibaba DFS的设计,也是多Master设计,它把Metadata的映射存储和管理分开了,由多个Metadata存储节点和一个查询Master节点组成。
多用户写,任意文件修改
  目前Hadoop只支持单用户写,不支持并发多用户写。可以使用Append操作在文件的末尾添加数据,但不支持在文件的任意位置进行修改。这些特性可能会在将来的版本中加入,但是这些特性的加入将会降低Hadoop的效率,就拿GFS来说吧,这篇文章里就说了google自己的人都用着Multiple Writers很不爽。
  利用Chubby、ZooKeeper之类的分布式协调服务来解决一致性问题。

大数据技术从业人员必读
一、Hadoop相关工具

  1. Hadoop
    Apache的Hadoop项目已几乎与大数据划上了等号。它不断壮大起来,已成为一个完整的生态系统,众多开源工具面向高度扩展的分布式计算。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://hadoop.apache.org

  1. Ambari
    作为Hadoop生态系统的一部分,这个Apache项目提供了基于Web的直观界面,可用于配置、管理和监控Hadoop集群。有些开发人员想把Ambari的功能整合到自己的应用程序当中,Ambari也为他们提供了充分利用REST(代表性状态传输协议)的API。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://ambari.apache.org

  1. Avro
    这个Apache项目提供了数据序列化系统,拥有丰富的数据结构和紧凑格式。模式用JSON来定义,它很容易与动态语言整合起来。

支持的操作系统:与操作系统无关。
相关链接:http://avro.apache.org

  1. Cascading
    Cascading是一款基于Hadoop的应用程序开发平台。提供商业支持和培训服务。

支持的操作系统:与操作系统无关。
相关链接:http://www.cascading.org/projects/cascading/

  1. Chukwa
    Chukwa基于Hadoop,可以收集来自大型分布式系统的数据,用于监控。它还含有用于分析和显示数据的工具。

支持的操作系统:Linux和OS X。
相关链接:http://chukwa.apache.org

  1. Flume
    Flume可以从其他应用程序收集日志数据,然后将这些数据送入到Hadoop。官方网站声称:“它功能强大、具有容错性,还拥有可以调整优化的可靠性机制和许多故障切换及恢复机制。”

支持的操作系统:Linux和OS X。
相关链接:https://cwiki.apache.org/confluence/display/FLUME/Home

  1. HBase
    HBase是为有数十亿行和数百万列的超大表设计的,这是一种分布式数据库,可以对大数据进行随机性的实时读取/写入访问。它有点类似谷歌的Bigtable,不过基于Hadoop和Hadoop分布式文件系统(HDFS)而建。

支持的操作系统:与操作系统无关。
相关链接:http://hbase.apache.org

  1. Hadoop分布式文件系统(HDFS)
    HDFS是面向Hadoop的文件系统,不过它也可以用作一种独立的分布式文件系统。它基于Java,具有容错性、高度扩展性和高度配置性。

支持的操作系统:Windows、Linux和OS X。
相关链接:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html

  1. Hive
    Apache Hive是面向Hadoop生态系统的数据仓库。它让用户可以使用HiveQL查询和管理大数据,这是一种类似SQL的语言。

支持的操作系统:与操作系统无关。
相关链接:http://hive.apache.org

  1. Hivemall
    Hivemall结合了面向Hive的多种机器学习算法。它包括诸多高度扩展性算法,可用于数据分类、递归、推荐、k最近邻、异常检测和特征哈希。

支持的操作系统:与操作系统无关。
相关链接:https://github.com/myui/hivemall

  1. Mahout
    据官方网站声称,Mahout项目的目的是“为迅速构建可扩展、高性能的机器学习应用程序打造一个环境。”它包括用于在Hadoop MapReduce上进行数据挖掘的众多算法,还包括一些面向Scala和Spark环境的新颖算法。

支持的操作系统:与操作系统无关。
相关链接:http://mahout.apache.org

  1. MapReduce
    作为Hadoop一个不可或缺的部分,MapReduce这种编程模型为处理大型分布式数据集提供了一种方法。它最初是由谷歌开发的,但现在也被本文介绍的另外几个大数据工具所使用,包括CouchDB、MongoDB和Riak。

支持的操作系统:与操作系统无关。
相关链接:http://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html

  1. Oozie
    这种工作流程调度工具是为了管理Hadoop任务而专门设计的。它能够按照时间或按照数据可用情况触发任务,并与MapReduce、Pig、Hive、Sqoop及其他许多相关工具整合起来。

支持的操作系统:Linux和OS X。
相关链接:http://oozie.apache.org

  1. Pig
    Apache Pig是一种面向分布式大数据分析的平台。它依赖一种名为Pig Latin的编程语言,拥有简化的并行编程、优化和可扩展性等优点。

支持的操作系统:与操作系统无关。
相关链接:http://pig.apache.org

  1. Sqoop
    企业经常需要在关系数据库与Hadoop之间传输数据,而Sqoop就是能完成这项任务的一款工具。它可以将数据导入到Hive或HBase,并从Hadoop导出到关系数据库管理系统(RDBMS)。

支持的操作系统:与操作系统无关。
相关链接:http://sqoop.apache.org

  1. Spark
    作为MapReduce之外的一种选择,Spark是一种数据处理引擎。它声称,用在内存中时,其速度比MapReduce最多快100倍;用在磁盘上时,其速度比MapReduce最多快10倍。它可以与Hadoop和Apache Mesos一起使用,也可以独立使用。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://spark.apache.org

  1. Tez
    Tez建立在Apache Hadoop YARN的基础上,这是“一种应用程序框架,允许为任务构建一种复杂的有向无环图,以便处理数据。”它让Hive和Pig可以简化复杂的任务,而这些任务原本需要多个步骤才能完成。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://tez.apache.org

  1. Zookeeper
    这种大数据管理工具自称是“一项集中式服务,可用于维护配置信息、命名、提供分布式同步以及提供群组服务。”它让Hadoop集群里面的节点可以彼此协调。

支持的操作系统:Linux、Windows(只适合开发环境)和OS X(只适合开发环境)。
相关链接:http://zookeeper.apache.org

二、大数据分析平台和工具

  1. Disco
    Disco最初由诺基亚开发,这是一种分布式计算框架,与Hadoop一样,它也基于MapReduce。它包括一种分布式文件系统以及支持数十亿个键和值的数据库。

支持的操作系统:Linux和OS X。
相关链接:http://discoproject.org

  1. HPCC
    作为Hadoop之外的一种选择,HPCC这种大数据平台承诺速度非常快,扩展性超强。除了免费社区版外,HPCC Systems还提供收费的企业版、收费模块、培训、咨询及其他服务。

支持的操作系统:Linux。
相关链接:http://hpccsystems.com

  1. Lumify
    Lumify归Altamira科技公司(以国家安全技术而闻名)所有,这是一种开源大数据整合、分析和可视化平台。你只要在Try.Lumify.io试一下演示版,就能看看它的实际效果。

支持的操作系统:Linux。
相关链接:http://www.jboss.org/infinispan.html

  1. Pandas
    Pandas项目包括基于Python编程语言的数据结构和数据分析工具。它让企业组织可以将Python用作R之外的一种选择,用于大数据分析项目。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://pandas.pydata.org

  1. Storm
    Storm现在是一个Apache项目,它提供了实时处理大数据的功能(不像Hadoop只提供批任务处理)。其用户包括推特、美国天气频道、WebMD、阿里巴巴、Yelp、雅虎日本、Spotify、Group、Flipboard及其他许多公司。

支持的操作系统:Linux。
相关链接:https://storm.apache.org

三、数据库/数据仓库

  1. Blazegraph
    Blazegraph之前名为“Bigdata”,这是一种高度扩展、高性能的数据库。它既有使用开源许可证的版本,也有使用商业许可证的版本。

支持的操作系统:与操作系统无关。
相关链接:http://www.systap.com/bigdata

  1. Cassandra
    这种NoSQL数据库最初由Facebook开发,现已被1500多家企业组织使用,包括苹果、欧洲原子核研究组织(CERN)、康卡斯特、电子港湾、GitHub、GoDaddy、Hulu、Instagram、Intuit、Netfilx、Reddit及其他机构。它能支持超大规模集群;比如说,苹果部署的Cassandra系统就包括75000多个节点,拥有的数据量超过10 PB。

支持的操作系统:与操作系统无关。
相关链接:http://cassandra.apache.org

  1. CouchDB
    CouchDB号称是“一款完全拥抱互联网的数据库”,它将数据存储在JSON文档中,这种文档可以通过Web浏览器来查询,并且用JavaScript来处理。它易于使用,在分布式上网络上具有高可用性和高扩展性。

支持的操作系统:Windows、Linux、OS X和安卓。
相关链接:http://couchdb.apache.org

  1. FlockDB
    由推特开发的FlockDB是一种非常快、扩展性非常好的图形数据库,擅长存储社交网络数据。虽然它仍可用于下载,但是这个项目的开源版已有一段时间没有更新了。

支持的操作系统:与操作系统无关。
相关链接:https://github.com/twitter/flockdb

  1. Hibari
    这个基于Erlang的项目自称是“一种分布式有序键值存储系统,保证拥有很强的一致性”。它最初是由Gemini Mobile Technologies开发的,现在已被欧洲和亚洲的几家电信运营商所使用。

支持的操作系统:与操作系统无关。
相关链接:http://hibari.github.io/hibari-doc/

  1. Hypertable
    Hypertable是一种与Hadoop兼容的大数据数据库,承诺性能超高,其用户包括电子港湾、百度、高朋、Yelp及另外许多互联网公司。提供商业支持服务。

支持的操作系统:Linux和OS X。
相关链接:http://hypertable.org

  1. Impala
    Cloudera声称,基于SQL的Impala数据库是“面向Apache Hadoop的领先的开源分析数据库”。它可以作为一款独立产品来下载,又是Cloudera的商业大数据产品的一部分。

支持的操作系统:Linux和OS X。
相关链接:http://www.cloudera.com/content/cloudera/en/products-and-services/cdh/impala.html

  1. InfoBright社区版
    InfoBright为数据分析而设计,这是一种面向列的数据库,具有很高的压缩比。InfoBright.com提供基于同一代码的收费产品,提供支持服务。

支持的操作系统:Windows和Linux。
相关链接:http://www.infobright.org

  1. MongoDB
    mongoDB的下载量已超过1000万人次,这是一种极其受欢迎的NoSQL数据库。MongoDB.com上提供了企业版、支持、培训及相关产品和服务。

支持的操作系统:Windows、Linux、OS X和Solaris。
相关链接:http://www.mongodb.org

  1. Neo4j
    Neo4j自称是“速度最快、扩展性最佳的原生图形数据库”,它承诺具有大规模扩展性、快速的密码查询性能和经过改进的开发效率。用户包括电子港湾、必能宝(Pitney Bowes)、沃尔玛、德国汉莎航空公司和CrunchBase。

支持的操作系统:Windows和Linux。
相关链接:http://neo4j.org

  1. OrientDB
    这款多模型数据库结合了图形数据库的一些功能和文档数据库的一些功能。提供收费支持、培训和咨询等服务。

支持的操作系统:与操作系统无关。
相关链接:http://www.orientdb.org/index.htm

  1. Pivotal Greenplum Database
    Pivotal声称,Greenplum是“同类中最佳的企业级分析数据库”,能够非常快速地对庞大的海量数据进行功能强大的分析。它是Pivotal大数据库套件的一部分。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://pivotal.io/big-data/pivotal-greenplum-database

  1. Riak
    Riak“功能完备”,有两个版本:KV是分布式NoSQL数据库,S2提供了面向云环境的对象存储。它既有开源版,也有商业版,还有支持Spark、Redis和Solr的附件。

支持的操作系统:Linux和OS X。
相关链接:http://basho.com/riak-0-10-is-full-of-great-stuff/

  1. Redis
    Redis现在由Pivotal赞助,这是一种键值缓存和存储系统。提供收费支持。要注意:虽然该项目并不正式支持Windows,不过微软在GitHub上有一个Windows派生版。

支持的操作系统:Linux。
相关链接:http://redis.io

四、商业智能

  1. Talend Open Studio
    Talend的下载量已超过200万人次,其开源软件提供了数据整合功能。该公司还开发收费的大数据、云、数据整合、应用程序整合和主数据管理等工具。其用户包括美国国际集团(AIG)、康卡斯特、电子港湾、通用电气、三星、Ticketmaster和韦里逊等企业组织。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://www.talend.com/index.php

  1. Jaspersoft
    Jaspersoft提供了灵活、可嵌入的商业智能工具,用户包括众多企业组织:高朋、冠群科技、美国农业部、爱立信、时代华纳有线电视、奥林匹克钢铁、内斯拉斯加大学和通用动力公司。除了开源社区版外,它还提供收费的报表版、亚马逊网络服务(AWS)版、专业版和企业版。

支持的操作系统:与操作系统无关。
相关链接:http://www.jaspersoft.com

  1. Pentaho
    Pentaho归日立数据系统公司所有,它提供了一系列数据整合和业务分析工具。官方网站上提供了三个社区版;访问Pentaho.com,即可了解收费支持版方面的信息。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://community.pentaho.com

  1. SpagoBI
    Spago被市场分析师们称为“开源领袖”,它提供商业智能、中间件和质量保证软件,另外还提供Java EE应用程序开发框架。该软件百分之分免费、开源,不过也提供收费的支持、咨询、培训及其他服务。

支持的操作系统:与操作系统无关。
相关链接:http://www.spagoworld.org/xwiki/bin/view/SpagoWorld/

  1. KNIME
    KNIME的全称是“康斯坦茨信息挖掘工具”(Konstanz Information Miner),这是一种开源分析和报表平台。提供了几个商业和开源扩展件,以增强其功能。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://www.knime.org

  1. BIRT
    BIRT的全称是“商业智能和报表工具”。它提供的一种平台可用于制作可以嵌入到应用程序和网站中的可视化元素及报表。它是Eclipse社区的一部分,得到了Actuate、IBM和Innovent Solutions的支持。

支持的操作系统:与操作系统无关。
相关链接:http://www.eclipse.org/birt/

五、数据挖掘

44.DataMelt
作为jHepWork的后续者,DataMelt可以处理数学运算、数据挖掘、统计分析和数据可视化等任务。它支持Java及相关的编程语言,包括Jython、Groovy、JRuby和Beanshell。
支持的操作系统:与操作系统无关。
相关链接:http://jwork.org/dmelt/

  1. KEEL
    KEEL的全称是“基于进化学习的知识提取”,这是一种基于Java的机器学习工具,为一系列大数据任务提供了算法。它还有助于评估算法在处理递归、分类、集群、模式挖掘及类似任务时的效果。

支持的操作系统:与操作系统无关。
相关链接:http://keel.es

  1. Orange
    Orange认为数据挖掘应该是“硕果累累、妙趣横生”,无论你是有多年的丰富经验,还是刚开始接触这个领域。它提供了可视化编程和Python脚本工具,可用于数据可视化和分析。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://orange.biolab.si

  1. RapidMiner
    RapidMiner声称拥有250000多个用户,包括贝宝、德勤、电子港湾、思科和大众。它提供一系列广泛的开源版和收费版,不过要注意:免费的开源版只支持CSV格式或Excel格式的数据。

支持的操作系统:与操作系统无关。
相关链接:https://rapidminer.com

  1. Rattle
    Rattle的全称是“易学易用的R分析工具”。它为R编程语言提供了一种图形化界面,简化了这些过程:构建数据的统计或可视化摘要、构建模型以及执行数据转换。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://rattle.togaware.com

  1. SPMF
    SPMF现在包括93种算法,可用于顺序模式挖掘、关联规则挖掘、项集挖掘、顺序规则挖掘和集群。它可以独立使用,也可以整合到其他基于Java的程序中。

支持的操作系统:与操作系统无关。
相关链接:http://www.philippe-fournier-viger.com/spmf/

  1. Weka
    怀卡托知识分析环境(Weka)是一组基于Java的机器学习算法,面向数据挖掘。它可以执行数据预处理、分类、递归、集群、关联规则和可视化。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://www.cs.waikato.ac.nz/~ml/weka/

六、查询引擎

  1. Drill
    这个Apache项目让用户可以使用基于SQL的查询,查询Hadoop、NoSQL数据库和云存储服务。它可用于数据挖掘和即席查询,它支持一系列广泛的数据库,包括HBase、MongoDB、MapR-DB、HDFS、MapR-FS、亚马逊S3、Azure Blob Storage、谷歌云存储和Swift。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://drill.apache.org

七、编程语言

  1. R
    R类似S语言和环境,旨在处理统计计算和图形。它包括一套整合的大数据工具,可用于数据处理、计算和可视化。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://www.r-project.org

  1. ECL
    企业控制语言(ECL)是开发人员用来在HPCC平台上构建大数据应用程序的语言。HPCC Systems官方网站上有集成开发环境(IDE)、教程以及处理该语言的众多相关工具。

支持的操作系统:Linux。
相关链接:http://hpccsystems.com/download/docs/ecl-language-reference

八、大数据搜索

  1. Lucene
    基于Java的Lucene可以非常迅速地执行全文搜索。据官方网站声称,它在现代硬件上每小时能够检索超过150GB的数据,它含有强大而高效的搜索算法。开发工作得到了Apache软件基金会的赞助。

支持的操作系统:与操作系统无关。
相关链接:http://lucene.apache.org/core/

  1. Solr
    Solr基于Apache Lucene,是一种高度可靠、高度扩展的企业搜索平台。知名用户包括eHarmony、西尔斯、StubHub、Zappos、百思买、AT&T、Instagram、Netflix、彭博社和Travelocity。

支持的操作系统:与操作系统无关。
相关链接:http://lucene.apache.org/solr/

九、内存中技术

  1. Ignite
    这个Apache项目自称是“一种高性能、整合式、分布式的内存中平台,可用于对大规模数据集执行实时计算和处理,速度比传统的基于磁盘的技术或闪存技术高出好几个数量级。”该平台包括数据网格、计算网格、服务网格、流媒体、Hadoop加速、高级集群、文件系统、消息传递、事件和数据结构等功能。

支持的操作系统:与操作系统无关。
相关链接:https://ignite.incubator.apache.org

  1. Terracotta
    Terracotta声称其BigMemory技术是“世界上数一数二的内存中数据管理平台”,声称拥有210万开发人员,250家企业组织部署了其软件。该公司还提供商业版软件,另外提供支持、咨询和培训等服务。

支持的操作系统:与操作系统无关。
相关链接:http://www.terracotta.org

  1. Pivotal GemFire/Geode
    今年早些时候,Pivotal宣布它将开放其大数据套件关键组件的源代码,其中包括GemFire内存中NoSQL数据库。它已向Apache软件基金会递交了一项提案,以便在“Geode”的名下管理GemFire数据库的核心引擎。还提供该软件的商业版。

支持的操作系统:Windows和Linux。
相关链接:http://pivotal.io/big-data/pivotal-gemfire

  1. GridGain
    由Apache Ignite驱动的GridGrain提供内存中数据结构,用于迅速处理大数据,还提供基于同一技术的Hadoop加速器。它既有收费的企业版,也有免费的社区版,后者包括免费的基本支持。

支持的操作系统:Windows、Linux和OS X。
相关链接:http://www.gridgain.com

  1. Infinispan
    作为一个红帽JBoss项目,基于Java的Infinispan是一种分布式内存中数据网格。它可以用作缓存、用作高性能NoSQL数据库,或者为诸多框架添加集群功能。

支持的操作系统:与操作系统无关。

分析一个程序的性能可以归结为回答4个基本的问题:

1.它运行的有多块?
2.那里是速度的瓶颈?
3.它使用了多少内存?
4.哪里发生了内存泄漏?

下面,我们将用一些很酷的工具,深入细节的回答这些问题。

使用time工具粗糙定时

首先,我们可以使用快速然而粗糙的工具:古老的unix工具time,来为我们的代码检测运行时间。

$ time python yourprogram.py
real 0m1.028s
user 0m0.001s
sys 0m0.003s

上面三个输入变量的意义在文章 stackoverflow article 中有详细介绍。简单的说:
real - 表示实际的程序运行时间
user - 表示程序在用户态的cpu总时间
sys - 表示在内核态的cpu总时间
通过sys和user时间的求和,你可以直观的得到系统上没有其他程序运行时你的程序运行所需要的CPU周期。

若sys和user时间之和远远少于real时间,那么你可以猜测你的程序的主要性能问题很可能与IO等待相关。

使用计时上下文管理器进行细粒度计时

我们的下一个技术涉及访问细粒度计时信息的直接代码指令。这是一小段代码,我发现使用专门的计时测量是非常重要的:
timer.py
import time
class Timer(object):

def __init__(self, verbose=False):
    self.verbose = verbose

def __enter__(self):
    self.start = time.time()
    return self

def __exit__(self, *args):
    self.end = time.time()
    self.secs = self.end - self.start
    self.msecs = self.secs * 1000  # millisecs
    if self.verbose:
        print 'elapsed time: %f ms' % self.msecs

为了使用它,你需要用Python的with关键字和Timer上下文管理器包装想要计时的代码块。它将会在你的代码块开始执行的时候启动计时器,在你的代码块结束的时候停止计时器。

这是一个使用上述代码片段的例子:

from timer import Timer
from redis import Redis
rdb = Redis()

with Timer() as t:

rdb.lpush("foo", "bar")

print "=> elasped lpush: %s s" % t.secs

with Timer as t:

rdb.lpop("foo")

print "=> elasped lpop: %s s" % t.secs
我经常将这些计时器的输出记录到文件中,这样就可以观察我的程序的性能如何随着时间进化。

使用分析器逐行统计时间和执行频率

Robert Kern有一个称作line_profiler的不错的项目,我经常使用它查看我的脚步中每行代码多快多频繁的被执行。
想要使用它,你需要通过pip安装该python包:
$ pip install line_profiler
一旦安装完成,你将会使用一个称做“line_profiler”的新模组和一个“kernprof.py”可执行脚本。
想要使用该工具,首先修改你的源代码,在想要测量的函数上装饰@profile装饰器。不要担心,你不需要导入任何模组。kernprof.py脚本将会在执行的时候将它自动地注入到你的脚步的运行时。
primes.py
@profile
def primes(n):

if n==2:
    return [2]
elif n<2:
    return []
s=range(3,n+1,2)
mroot = n ** 0.5
half=(n+1)/2-1
i=0
m=3
while m <= mroot:
    if s[i]:
        j=(m*m-3)/2
        s[j]=0
        while j<half:
            s[j]=0
            j+=m
    i=i+1
    m=2*i+3
return [2]+[x for x in s if x]

primes(100)
一旦你已经设置好了@profile装饰器,使用kernprof.py执行你的脚步。
$ kernprof.py -l -v fib.py
-l选项通知kernprof注入@profile装饰器到你的脚步的内建函数,-v选项通知kernprof在脚本执行完毕的时候显示计时信息。上述脚本的输出看起来像这样:
Wrote profile results to primes.py.lprof
Timer unit: 1e-06 s

File: primes.py
Function: primes at line 2
Total time: 0.00019 s

Line #      Hits         Time  Per Hit   % Time  Line Contents

==============================================================

 2                                           @profile
 3                                           def primes(n): 
 4         1            2      2.0      1.1      if n==2:
 5                                                   return [2]
 6         1            1      1.0      0.5      elif n<2:
 7                                                   return []
 8         1            4      4.0      2.1      s=range(3,n+1,2)
 9         1           10     10.0      5.3      mroot = n ** 0.5
10         1            2      2.0      1.1      half=(n+1)/2-1
11         1            1      1.0      0.5      i=0
12         1            1      1.0      0.5      m=3
13         5            7      1.4      3.7      while m <= mroot:
14         4            4      1.0      2.1          if s[i]:
15         3            4      1.3      2.1              j=(m*m-3)/2
16         3            4      1.3      2.1              s[j]=0
17        31           31      1.0     16.3              while j<half:
18        28           28      1.0     14.7                  s[j]=0
19        28           29      1.0     15.3                  j+=m
20         4            4      1.0      2.1          i=i+1
21         4            4      1.0      2.1          m=2*i+3
22        50           54      1.1     28.4      return [2]+[x for x in s if x]

寻找具有高Hits值或高Time值的行。这些就是可以通过优化带来最大改善的地方。

程序使用了多少内存?

现在我们对计时有了较好的理解,那么让我们继续弄清楚程序使用了多少内存。我们很幸运,Fabian Pedregosa模仿Robert Kern的line_profiler实现了一个不错的内存分析器。

首先使用pip安装:

$ pip install -U memory_profiler
$ pip install psutil
(这里建议安装psutil包,因为它可以大大改善memory_profiler的性能)。

就像line_profiler,memory_profiler也需要在感兴趣的函数上面装饰@profile装饰器:

@profile
def primes(n):

...
...

想要观察你的函数使用了多少内存,像下面这样执行:
$ python -m memory_profiler primes.py
一旦程序退出,你将会看到看起来像这样的输出:
Filename: primes.py

Line #    Mem usage  Increment   Line Contents

==============================================

 2                           @profile
 3    7.9219 MB  0.0000 MB   def primes(n): 
 4    7.9219 MB  0.0000 MB       if n==2:
 5                                   return [2]
 6    7.9219 MB  0.0000 MB       elif n<2:
 7                                   return []
 8    7.9219 MB  0.0000 MB       s=range(3,n+1,2)
 9    7.9258 MB  0.0039 MB       mroot = n ** 0.5
10    7.9258 MB  0.0000 MB       half=(n+1)/2-1
11    7.9258 MB  0.0000 MB       i=0
12    7.9258 MB  0.0000 MB       m=3
13    7.9297 MB  0.0039 MB       while m <= mroot:
14    7.9297 MB  0.0000 MB           if s[i]:
15    7.9297 MB  0.0000 MB               j=(m*m-3)/2
16    7.9258 MB -0.0039 MB               s[j]=0
17    7.9297 MB  0.0039 MB               while j<half:
18    7.9297 MB  0.0000 MB                   s[j]=0
19    7.9297 MB  0.0000 MB                   j+=m
20    7.9297 MB  0.0000 MB           i=i+1
21    7.9297 MB  0.0000 MB           m=2*i+3
22    7.9297 MB  0.0000 MB       return [2]+[x for x in s if x]

line_profiler和memory_profiler的IPython快捷方式

memory_profiler和line_profiler有一个鲜为人知的小窍门,两者都有在IPython中的快捷命令。你需要做的就是在IPython会话中输入以下内容:

%load_ext memory_profiler
%load_ext line_profiler
在这样做的时候你需要访问魔法命令%lprun和%mprun,它们的行为类似于他们的命令行形式。主要区别是你不需要使用@profiledecorator来修饰你要分析的函数。只需要在IPython会话中像先前一样直接运行分析:

In [1]: from primes import primes
In [2]: %mprun -f primes primes(1000)
In [3]: %lprun -f primes primes(1000)
这样可以节省你很多时间和精力,因为你的源代码不需要为使用这些分析命令而进行修改。

内存泄漏在哪里?

cPython解释器使用引用计数做为记录内存使用的主要方法。这意味着每个对象包含一个计数器,当某处对该对象的引用被存储时计数器增加,当引用被删除时计数器递减。当计数器到达零时,cPython解释器就知道该对象不再被使用,所以删除对象,释放占用的内存。

如果程序中不再被使用的对象的引用一直被占有,那么就经常发生内存泄漏。

查找这种“内存泄漏”最快的方式是使用Marius Gedminas编写的objgraph,这是一个极好的工具。该工具允许你查看内存中对象的数量,定位含有该对象的引用的所有代码的位置。

一开始,首先安装objgraph:
pip install objgraph
一旦你已经安装了这个工具,在你的代码中插入一行声明调用调试器:
import pdb; pdb.set_trace()

最普遍的对象是哪些?

在运行的时候,你可以通过执行下述指令查看程序中前20个最普遍的对象:

(pdb) import objgraph
(pdb) objgraph.show_most_common_types()

MyBigFatObject 20000
tuple 16938
function 4310
dict 2790
wrapper_descriptor 1181
builtin_function_or_method 934
weakref 764
list 634
method_descriptor 507
getset_descriptor 451
type 439

哪些对象已经被添加或删除?

我们也可以查看两个时间点之间那些对象已经被添加或删除:

(pdb) import objgraph
(pdb) objgraph.show_growth()
.
.
.
(pdb) objgraph.show_growth() # this only shows objects that has been added or deleted since last show_growth() call

traceback 4 +2
KeyboardInterrupt 1 +1
frame 24 +1
list 667 +1
tuple 16969 +1

谁引用着泄漏的对象?

继续,你还可以查看哪里包含给定对象的引用。让我们以下述简单的程序做为一个例子:

x = [1]
y = [x, [x], {"a":x}]
import pdb; pdb.set_trace()
想要看看哪里包含变量x的引用,执行objgraph.show_backref()函数:
(pdb) import objgraph
(pdb) objgraph.show_backref([x], filename="/tmp/backrefs.png")
该命令的输出应该是一副PNG图像,保存在/tmp/backrefs.png,它看起来是像这样:
09092835_V08x.png
最下面有红字的盒子是我们感兴趣的对象。我们可以看到,它被符号x引用了一次,被列表y引用了三次。如果是x引起了一个内存泄漏,我们可以使用这个方法,通过跟踪它的所有引用,来检查为什么它没有自动的被释放。

回顾一下,objgraph 使我们可以:

显示占据python程序内存的头N个对象
显示一段时间以后哪些对象被删除活增加了
在我们的脚本中显示某个给定对象的所有引用