在控制台相同位置变化字符

这个标题看上去是比较奇怪的,因为我实在没想好应该怎么说 :p

实际上就是要一种效果,我们经常会写一些脚本操作一些数据什么的,通常会在控制台输出一些日志来监测脚本运行的情况,或者我们常见的在某些linux安装软件时会出现的一个由字符组成的旋转图标。

要实现这个效果,原理就是先输出一个字符,然后在把他删除掉,接着再输出,循环下去就像动画了。

Shell 里是这样的

while(true); do
for a in \\ \| \/ -; do
echo -n $a
sleep 1
echo -n -e \\r # echo -n -e \\b
done
done

Java 里是这样的

char progress[] = { ‘-’, ‘\\’, ‘|’, ‘/’ };
int progressCycle = 0;
for ( int i = 0; i < 20; i++ ){
try{
Thread.sleep( 250 );
}catch ( InterruptedException e ){
}
System.out.print( progress[ progressCycle ] + "\b" );
progressCycle = ( progressCycle + 1 ) & 3;
}

Web Architecture

话说看了那么多架构的文章,也没总结一下,今天猛然看到一份列表,直接抄下来了,相当不错,以后也会不定期更新这个列表的。

(内容来自 http://www.54chen.com/154-著名网站架构设计)

Gentoo 下的 JAVA 乱码

今天在 Gentoo 下执行一个 Java 程序,因为 locale 不是 UTF-8,所以不管怎么处理程序,输出的都是乱码,GOOGLE 了一下,发现了解决方法,在 Java 执行的时候加几个参数就好了

-Ddefault.client.encoding=UTF8 -Dfile.encoding=UTF8 -Duser.language=Zh

Tips of Solr

这几天在折腾 Solr,还是发现了一些使用的 Tips 和问题,记录一下。

搜索准确度

搜索的准确度,基本上还是跟 分词算法有关系。而分词算法根据实现方式分为,基于字符串匹配的分词,基于理解的分词,基于统计的分词。后两种分词算法实现相对比较复杂,所以一般现在站 内搜索多使用基于字符串匹配,也就是所谓的基于字典的算法。这样准确程度又和字典中有相当的关系。

分词算法

目前市面上有不少开源的中文分词算法,都不错,有文章专门研究,这里就不讨论了。

排序

  • 根据 Solr 的语法,指定 sort 变量,类似这样 sort=create_ts desc
  • 或者在创建索引时给不同的文档加入不同的 boost 值,在使用默认的按照相关度排序中,这个 boost 的值会起到作用

索引文件大小

索引文件过大,可能引起搜索效率下降,解决方法有两个

  1. 在创建索引时不保存内容,只保存 ID,检索出 ID 再从 Cache 里边查询具体的对象,这样可以保证索引大小在一个可控的范围内。(手机之家只保存ID,3000万的帖子,索引大小4G左右)
  2. 使用分布式,从 1.4 开始 Solr 已经能支持分布式部署了,并且可以使用任意一台服务器作为主服务器,索引分别分布在不同的服务器上,通过主服务器查询,并且合并搜索结果返回。
    • 被索引的文档必须全局唯一(不同的服务器服务不同的索引,并且索引ID不同)
    • 不支持全局 IDF,意味着也许不是最佳排序

搜索效率/吞吐量

  • 选择较好的分析器 – 这个优化主要是对磁盘空间的优化,可以将索引文件减小。但是对时间并没有什么帮助,甚至会需要更长时 间,因为较好的分析器需要匹配词库,会消耗更多cpu。
  • 将索引放入内存 – 这是一个最直观的想法,因为内存比磁盘快很多。Lucene提供了RAMDirectory可以在内存中容纳索引,然后再把内存中的数据写入硬盘。
  • 使用NIOFSDirectory – lucene 2.4 开始有一个 NIOFSDirectory 实现,使用 java.nio’s FileChannel 读取文件。官方说:在大多数非 windows 平台下,多个线程共用单个 searcher 比 FSDirectory(在同一时刻只能一个线程使用 searcher)可以提高查询的吞吐量。
  • 在 Tomcat 的启动脚本中加入一个 JAVA OPTS 配置 -Dorg.apache.lucene.FSDirectory.class=org.apache.lucene.store.NIOFSDirectory
  • 使用 Http11NioProtocol(tomcat)可以进一步地提高吞吐量 这个方法被证明在提交数据量比较大的XML时候会出现接收字节流不完整的情况。
  • 通过分布式架构也能提高吞吐量,参考上一节的描述。

创建索引脚本

  • 根据W3C的标准,以下16进制的字符是不被允许出现在XML文件中的,即使放在<![CDATE[]]> 中,也不能幸免遇难,会引起 Solr 对 XML 处理的错误,从而导致创建索引失败,所以在提交数据之前把这些字符过滤掉。
  • \x00-\x08, \x0b-\x0c, \x0e-\x1f
  • 在 PHP 可以用这个方法  return preg_replace(’@[\x00-\x08\x0B\x0C\x0E-\x1F]@’, ”, $string);
  • 另外,在给 Solr 提交数据的时候要注意提交的 xml 文件/数据大小,如果太大可能会出现各种莫名奇妙的问题,Solr 会说你的 XML 格式不正确,缺少闭合标签,解析不了。

Solr 补丁

Solr 1.3 在处理字符高亮时候对 unicode 的处理有问题,在搜索加上高亮选项会出现错误。打一个补丁后解决这个问题:

key-value databases

好久没有写过什么文章了,最近正好对 key-value 数据库做了一些调查,有一些初步的想法,就放这吧。

关于考察这些 key-value 数据库项目的一些指标或特性,我考虑以下一些属性:1. 是否有真实的应用(重量级玩家支持) 2. 扩展性/分布性 3. 客户端协议/语言封装 4. 参考实现 5. 实现语言 6. 其他特性 7. 性能(性能没时间一一测试,可以接下来进一步研究)。

可以被称之为 key-value 数据库的产品远不止我下边列的这些,但其他一些没有什么特别的背景和成功案例。对于这些产品我发现基本上分为三种类型,1. 存储引擎 2. 基于存储引擎的分布式框架 3. 更复杂的分布式DBMS。

可以说从功能上说每一个层次都比上一个层次的功能和复杂度更高。

  • MemcacheDB:基于Memcached源代码,添加了bdb作为持久存储,其他和Memecached没太大区别。
  • Tokyo Cabinet/Tyrant:TC/TT 本身只是一个存储引擎; 加上LightCloud后构成一个相对比较完整的分布式方案。不但可以支持字符串属性,还可以支持表和字段模式。
  • Redis:只提供存储引擎,存储时先放在内存中,然后再根据相关指令进行持久存储。可以存储列表和集合,可以对这两种数据结构直接进行原子操作push/pop,add/remove,按范围选择列表重元素等。可以用客户端的分布式算法进行patition。

这三种基本上只提供了存储引擎,在使用上和memcache并无太大区别,需要在客户端实现一些分布策略和管理,其中 TC/TT 被提及的是比较多的,因为来自于成功案例,并且被评测效率速度也比较好。

  • LightCloud:
  • Flare:基于Memcached协议;可配置存储引擎目前支持TC;自动数据分区(到master);提供proxy,访问那个结点对客户端透明;支持动态重建和分区(无须影响服务);节点监测自动错误隔离;可以使用超过256字节的key,超过1M的值;

这两种,都是基于基于 TC 引擎的分布式框架,可以在服务器端完成一些自动复制/数据分区/容错等功能,给客户端提供相对透明的API,不用太在意那些分布策略。

  • Cassandra:对客户端透明的容错,内置数据分区/复制策略和负载均衡。还提供了面向字段的数据结构。提供分布式,高科用性以及集群环境。”eventually consistent” model 。master-master模式。
  • Voldemort:自动复制,数据分区,容错;可扩展的序列化支持;支持master-master模式;内置cache支持;存储引擎可替换(bdb/mysql/memory/filesystem);支持服务器路由和客户端路由
  • HyperTable:基本是 Google BigTable 的一个实现,当前版本还比较初级只支持基本的查询操作,单条查询响应时间并不理想(数据量大可能有点优势?),可扩展性比较好,只要在集群中增加服务器就 可以扩展;数据根据主键自动分布由不同的RangeServer管理;数据最终可以存储在任何FS上,比如本地文件西东或者分布式文件系统如 HDFS/KFS等,最终数据存放在分布式文件系统中有单一服务器出问题,不会影响整体的数据
  • HBase:基本特性跟HyperTable类似,都是基于BitTable模型,不过作为Hadoop的子项目,文件系统就支持HDFS,和Hadoop的集成自然比较好。
  • MongDB:基于集合的存储机制,采用Json格式存储数据;有动态查询语言;支持全文索引;支持复制和failover,以及自动patition;支持二进制大数据存储(photo/video);目标是集成关系数据库和kv数据的优点为一身的DBMS
  • CouchDB:支持自动复制master-master模式,有自动双向解决冲突的机制;采用RESTful Jason格式的API;有基于web的管理工具;支持查询和索引,并且可以提供基于javascript的面向表的查询引擎;有第三方的工具lounge(meebo.com) 可以做patition,内建的patition开发中;

这一些是相对更复杂,目标更大的产品,都以某些论文(特别是Amazon的Dynamo,以及Google的BigTable)为基础或者深受其影响的实现产品。提供更完备的分布式KV数据管理系统,功能上有更复杂更有效的自动复制/容错/分区,有基于表/字段结构的数据结构,支持动态查询语言,全文检索,以及监控等高级功能,更像是完备的分布式DBMS。

下边的表格列出上边提到的一些特性:

项目名称 重量级玩家 扩展性/分布式 客户端协议/语言封装 参考实现 实现语言
MemcacheDB Sina Replication Memcached Memcached C
Tokyo Cabinet/Tyrant/LightCloud Mixi.jp / Plurk.com Replication, partition(LightCloud) Cabinet(C/Perl/Java/Ruby/Lua) / Memcached Dynamo C
Redis None Replication, partition PHP / Ruby / Python / Java / Erlang None C
Flare None Replication,partation Memcached Memcached C
Cassandra Facebook / Digg / Rackspace Replication,partition Thrift Dynamo/BigTable Java
Voldemort LinkedIn Replication,partition Protocol Buffers / Thrift / Java Serialization / Json None Java
HyperTable Baidu / ZEvents Replication,partition Thrift / C++ BigTable C++
HBase Yhaoo / Powerset / Ning Replication,partition Java BigTable Java / HTTP / Thrift
MongoDB SourceForge / Disqus Replication,partition PHP / Python / Java / Ruby / C++ / Perl None C++
CouchDB BBC / Meebo / UbuntuOne Replication,partition HTTP None Erlang

Next Page »