- 浏览: 236325 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
akka_li:
学习了!但是为什么后续的没有了?!
EJB4:RMI和RMI-IIOP -
springaop_springmvc:
apache lucene开源框架demo使用实例教程源代码下 ...
Lucene学习笔记(一)Lucene入门实例 -
qepipnu:
求solr 客户端 jar包
Solr学习笔记(三)Solr客户端开发实例 -
zhangbc:
是这问题,赞!
Oracle Start Up 2 Oracle 框架构件、启动、解决一个问题 -
feilian09:
查询 select hibernate jdbc 那个效率快
Hibernate,JDBC性能探讨
本文的目的是展示一个测试结果:Cassandra应用的高效性,稳定性,可靠性。具体:应用Cassandra记录Application运行中的日志。
首先说明在一个Application中,不管是它在运行过程,还是在它的开发过程中,记录日志是非常有必要的,特别是一些Service-Based Application或Distributed系统。通过日志,Application的维护人员和开发人员可以更好的完成他们的工作。Log4j是一个很好的日志记录开源工具包,它可以将日志记录到文件系统、从Console输出、发送到指定邮箱等等。本文就是先对Log4j做一扩展,写一个自己的CassandraAppender,使其具有将日志保存到Cassandra的功能。具体实现Log4j定义的Appender……,如下
1. 首先Log4j结构:
Log4j包括三个主要组件:
Logger:用来记录日志,可以对她指定记录级别(ALL,DEBUG,INFO,WARN,ERROR,FATA);
Layout:设置日志记录样式;
Appender:指定日志输出位置。
这里主要研究Appender,先看下图:
如图所示为Appender主要UML类图,AppenderSkeleton为抽象类,它实现了 org.apache.log4j.Appender
和 org.apache.log4j.spi.OptionHandler
接口,所有的 appender 都必须扩展org.apache.log4j.AppenderSkeleton
类,
当然我们这里的CassandraAppender就是通过继 AppenderSkeleton来实现的 。在抽象类AppenderSkeleton中定义了抽象方法:
abstract protected void append(LoggingEvent event);
所有的子类都要事先此方法,此方法中参数LoggingEvent代表日志信息,可以通过它获取日志名字,LoggerInfo等,此类还定义一方法:
public void activateOptions() { }
如果需要对某些参数做一处理,本文中CassandraAppender就是在此方法中初始化Thrift RPC连接;
2. Appender生命周期,如下图:
appender 实例不存在。或许框架还没有配置好。
框架实例化了一个新的 appender。这发生在配置器类分析配置脚本中的一个 appender 声明的时候。配置器类调用 Class.newInstanceYourCustomAppender.class) ,这等价于动态调用
new YourCustomAppender()
。框架这样做是为了避免被硬编码为任何特定的 appender 名称;框架是通用的,适用于任何 appender。
框架判断 appender 是否需要 layout。如果该 appender 不需要 layout,配置器就不会尝试从配置脚本中加载 layout 信息。
如图CassandraAppender处于就绪状态时,将系统日志发送到Cassandra服务器是它的唯一任务,具体我给出源代码:
Log4j 配置器调用 setter 方法。在所有属性都已设置好之后,框架就会调用这个方法。我们可以在这里激活必须同时激活的属性。
配置器调用 activateOptions() 方法。在所有属性都已设置好之后,框架就会调用这个方法。程序员可以在这里激活必须同时激活的属性。
Appender 准备就绪。 此刻,框架可以调用 append() 方法来处理日志记录请求。这个方法由 AppenderSkeleton.doAppend() 方法调用。
最后,关闭appender。 当框架即将要删除您的自定义 appender 实例时,它会调用您的 appender 的 close()
方法。 close()
是一个清理方法,意味着 您需要释放已分配的所有资源。它是一个必需的方法,并且不接受任何参数。它必须把 closed
字段设置为 true
,并在有人尝试使用关闭的 appender 时向框架发出警报。
3. 扩展自己的Appender
如下图所示为CassandraAppender工作原理:
package com.xxx.log4j; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.UUID; import org.apache.cassandra.thrift.Cassandra; import org.apache.cassandra.thrift.ColumnPath; import org.apache.cassandra.thrift.ConsistencyLevel; import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.TimedOutException; import org.apache.cassandra.thrift.UnavailableException; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Logger; import org.apache.log4j.spi.LoggingEvent; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; public class CassandraAppender extends AppenderSkeleton { Logger logger = Logger.getLogger(CassandraAppender.class); private TTransport tr; private Cassandra.Client client; private String keyspace; private String columnFamily; private String thriftAddress; private int thriftPort; private String keyStrategy; public CassandraAppender() { } public void activateOptions() { tr = new TSocket(thriftAddress, thriftPort); TProtocol proto = new TBinaryProtocol(tr); client = new Cassandra.Client(proto); try { tr.open(); } catch (TTransportException e) { e.printStackTrace(); } } public String getKeyspace() { return keyspace; } public void setKeyspace(String keyspace) { this.keyspace = keyspace; } public String getColumnFamily() { return columnFamily; } public void setColumnFamily(String columnFamily) { this.columnFamily = columnFamily; } public String getThriftAddress() { return thriftAddress; } public void setThriftAddress(String thriftAddress) { this.thriftAddress = thriftAddress; } public int getThriftPort() { return thriftPort; } public void setThriftPort(int thriftPort) { this.thriftPort = thriftPort; } public String getKeyStrategy() { return keyStrategy; } public void setKeyStrategy(String keyStrategy) { this.keyStrategy = keyStrategy; } protected void append(LoggingEvent event) { if(client == null) { System.out.println("client == null"); } try { client.insert( keyspace, event.getLoggerName(), getColumnPath(columnFamily,event), getStoreValue(event), new Date().getTime(), ConsistencyLevel.ONE ); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (InvalidRequestException e) { e.printStackTrace(); } catch (UnavailableException e) { e.printStackTrace(); } catch (TimedOutException e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } } private ColumnPath getColumnPath(String columnFamily, LoggingEvent event) throws UnsupportedEncodingException { ColumnPath path = new ColumnPath(); path.setColumn_family(columnFamily); if(getKeyStrategy().equals("uuid")) { UUID uuid = UUID.randomUUID(); String str = uuid.toString(); path.setColumn(str.getBytes()); } else { path.setColumn((event.getLocationInformation().getMethodName() + "-" + event.getLocationInformation().getLineNumber() + new Date().getTime()).getBytes("UTF-8")); } return path; } private byte[] getStoreValue(LoggingEvent event) throws UnsupportedEncodingException { return (event.getMessage()+ "").getBytes("UTF-8"); } public void close() { if(tr.isOpen()) { tr.close(); } } public boolean requiresLayout() { return false; } }
4. 测试
首先在配置Log4j日志文件log4j.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" > <appender name="Cassandra" class="com.xxx.log4j.CassandraAppender"> <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/> <param name="keyspace" value="Twitter"/> <param name="ColumnFamily" value="Users"/> <param name="ThriftAddress" value="0.0.0.0"/> <param name="ThriftPort" value="9160"/> <param name="keyStrategy" value="uuid"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c{1}] %m%n"/> </layout> </appender> <root> <priority value="INFO" /> <appender-ref ref="Cassandra"/> </root> </log4j:configuration>
然后运行自己测试类:
public class Log4jTestOne { static Logger logger = Logger.getLogger(Log4jTestOne.class); public static void main(String[] args) { Date start = new Date(); for(int i = 0 ; i < 100000 ; i ++) { logger.info("info"); } Date end = new Date(); System.out.println("Completed spent time: " + (end.getTime() - start.getTime())); } }
接着到Cassandra查看结果,可以用Cassandra Thrift访问(我会就Cassandra Client有专门Blog)
完
发表评论
-
Oracle - Add Exist Validation Before Create Table
2011-11-07 13:49 1406Usually we need to check the ta ... -
Oracle - An Managing Lob examples
2011-10-30 17:28 1384I met a request: I need to read ... -
PL/SQL Studing Notes
2011-10-20 21:48 1328As an extension of native ... -
一组Linux命令
2011-09-29 13:09 1427今天做测试发现Oracle服务器磁盘使用率达到100%导致Or ... -
Thinking in JDBC
2011-09-22 20:56 1818This blog will beas on a series ... -
Oracle Reference Exception Gallery
2011-07-05 22:28 1590The Following Exception is real ... -
SQL Studying Note I - Join
2011-07-02 10:28 1183SQL Join SQL Join are u ... -
Windows批处理脚步实例-创建Oracle数据库用户并向该用户添加数据
2010-12-11 09:25 3398Windows批处理使用方便、 ... -
Oracle starting up 5: Oracle 10g在WINDOWS服务中有5个Oracle服务项及解决与服务项相关的几个问题
2010-10-10 17:25 2295在Windows下安装Oracle 10g,安装完后在WIND ... -
Oracle starting up 5: Oracle数据库基础(续)
2010-10-07 14:15 0通用函数; 通用函数用于任何类型数据(包括空值) ... -
Oracle starting up 4: Oracle 10g 客户端 enterprise manager console 消失问题
2010-10-06 15:20 4265在家装了台服务器,因为家里电脑不行,所以服务器和客 ... -
Oracle Start Up 3:Oracle数据库基础
2010-10-05 20:17 21321. 创建TableSpace、用户及给用户分派权限 ... -
Oracle Start Up 2 Oracle 框架构件、启动、解决一个问题
2010-10-02 14:07 34664Warming Up: 本文 ... -
Oracle Start Up 1: 几个概念和Oracle数据库的物理结构和逻辑结构
2010-09-29 23:31 1988Oracle 基本概念 数据库(Database) ... -
Oracle 连接错误;ORA-27101: shared memory realm does not exist
2010-09-28 14:27 26276XP下安装Oracle10g 昨天下午刚安装完可以连接(Sq ... -
SQL Server 2005 dev 学习(1)
2010-09-26 15:14 1941关键字:SqlServer2005Dev版本安装 SQL Se ... -
Cassandra Dev 2: Cassandra入门(续) - Cassandra Cluster
2010-08-09 13:56 57265. Cassandra CLI 一般数据库服务器都会提供一 ... -
Cassandra Dev 1: Cassandra 入门
2010-08-06 17:55 4567最近, Cassandra 绝对是一个比较前端的话题 ...
相关推荐
DevCenter cassandra客户端 DevCenter cassandra客户端 DevCenter cassandra客户端
该库使您可以将Cassandra表公开为Spark RDD和数据集/数据框架,将Spark RDD和数据集/数据框架写入Cassandra表,并在Spark应用程序中执行任意CQL查询。 与Apache Cassandra 2.1或更高版本兼容(请参见下表) 与...
卡桑德拉网演示版特征主题黑暗表格行上一页下一页表格行编辑表格行过滤器表格行删除表名查找表定义表导出表导入CQL查询支持的Cassandra版本2.1.x 2.2.x 3.xx 是的是的是的用法下载$ wget ...解压缩$ tar zxvf linux.tar...
Cassandra导出器是一个独立的应用程序,可通过Prometheus友好端点导出Apache Cassandra指标。 TL; DR $ docker run --name cassandra-exporter bitnami/cassandra-exporter:latest 为什么要使用Bitnami Images? ...
Apache Cassandra构建工具 Jenkins Job DSL脚本创建CI作业: jenkins-dsl/ Jenkins Job构建/测试运行时脚本: build-scripts/ Apache Cassandra打包实用程序: cassandra-release/ docker/ 建筑包 创建包含构建...
cassandra-phantom:Cassandra + Phantom示例
cassandra出口商 cassandra-exporter是Java代理(具有可选的独立模式),可将Cassandra指标导出到 。 项目状态:测试版介绍cassandra-exporter可以实现Cassandra指标的高性能收集,并遵循Prometheus最佳做法进行指标...
用于Cassandra的Kubernetes运算符 网站: : Wiki: : 说明文件: : 建立 项目状态:Alpha Cassandra Operator管理部署到Cassandra集群,并自动执行与操作Cassandra集群相关的任务。 当前,面向用户的...
terraform-cassandra-multinode:使用terraform设置3个节点的Cassandra集群
卡桑德拉迁移描述Cassandra Migrations是用于Rails应用程序的Cassandra数据库架构迁移库。 该宝石提供: 多环境数据库配置版本化的CQL模式迁移管理用于简化迁移代码的模式修改DSL 用于数据库架构管理的瑞克任务支持...
卡桑德拉审计在Cassandra 4之前,开源版本不包含审核功能。 这是设计用于在Elasticsearch中归档查询日志的概念证明。 按照相同的原则,可以将日志存储在任何其他数据存储中(Cassandra,Mysql,Postgress)(欢迎...
备份:java -jar cassandra-backup-jar-with-dependencies.jar备份/ opt / cassandra /数据方案/tmp/backup.tar 还原:java -jar cassandra-backup-jar-with-dependencies.jar还原/ opt / cassandra /数据方案/tmp/...
机器人名称: Cassandra#9492 机器人编号: 742030317451214888 所需权限: 2080767094 Bot库: discord.py 简短说明:您是否曾经想过一个不需要设置的非常简单的机器人? 一个在您的服务器上美观的机器人,并...
机器人名称: Cassandra#9492 机器人编号: 742030317451214888 所需权限: 2080767094 Bot库: discord.py 简短说明:您是否曾经想过一个不需要设置的非常简单的机器人? 一个在您的服务器上美观的机器人,并能很...
devicehive-plugin-cassandra-node 用Node.js编写的DeviceHive Cassandra存储插件 概述 此插件使您可以在Cassandra中存储通过DeviceHive平台获得的命令和通知。 该应用程序包括两部分:模式创建服务和在docker-...
中国Cassandra数据库用户组(China Cassandra User Group) 是全世界排名第二的NoSQL数据库 Cassandra下载: Cassandra的文档: Cassandra的JIRA: Cassandra的源代码: Cassandra的技术博客: Cassandra的Meetup ...
Cassandra The Definitive Guide(2nd) 英文azw3 第2版 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
这是 Apache Cassandra 项目的令牌生成器在 Go 中的实现。 这实现了令牌生成能力,而无法生成显示环的 HTML 图形。 此外,您现在可以以标准 JSON 格式或打印精美的 JSON 格式输出数据。 这将允许您使用该工具生成...
Cassandra exporter 是 cassandra 的数据导出/导入工具,它使用简单,适用于 unicode 和复杂数据类型。 它是用 Javascript 开发的,导出的数据存储在 JSON 格式的文件中。 为什么是另一个工具? Cassandra 有一些很...
CASSANDRA_DIR=~/path/to/cassandra nosetests 使用 ccm 功能从 archives.apache.org 下载/编译已发布的源代码: CASSANDRA_VERSION=1.0.0 nosetests 如果测试定期针对同一个现有目录运行,一个方便的选择是在~/....