diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..6a3cba6
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/.project b/.project
new file mode 100644
index 0000000..0d2f4df
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ logcount
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..839d647
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..60105c1
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/README.md b/README.md
index 2126131..f130fba 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,120 @@
-# logcount
+# 日志分析系统
+
+## 系统架构
+
+ 本使用kafka,spark,hbase开发日志分析系统。
+
+
+
+### 软件模块
+
+ * Kafka:作为日志事件的消息系统,具有分布式,可分区,可冗余的消息服务功能。
+ * Spark:使用spark stream功能,实时分析消息系统中的数据,完成计算分析工作。
+ * Hbase:做为后端存储,存储spark计算结构,供其他系统进行调用
+
+## 环境部署
+
+### 软件版本
+
+ * hadoop 版本 : Hadoop相关软件如zookeeper、hadoop、hbase,使用的是cloudera的 cdh 5.2.0 版本。
+ * Kafka : 2.9.2-0.8.1.1
+
+### 软件安装
+
+a. 部署kafka
+
+ tar -xzf kafka_2.9.2-0.8.1.1.tgz
+
+b. 编辑kafka 配置文件
+
+ config/server-1.properties:
+ broker.id=0
+ port=9093
+ log.dir=/tmp/kafka-logs
+
+ config/server-2.properties:
+ broker.id=1
+ port=9093
+ log.dir=/tmp/kafka-logs
+
+ config/server-3.properties:
+ broker.id=2
+ port=9093
+ log.dir=/tmp/kafka-logs
+
+c. 启动kafka
+
+ bin/kafka-server-start.sh config/server-1.properties &
+ bin/kafka-server-start.sh config/server-2.properties &
+ bin/kafka-server-start.sh config/server-3.properties &
+
+d. 创建kafka topic
+
+> bin/kafka-topics.sh --create --zookeeper 10.10.102.191:2181, 10.10.102.192:2181, 10.10.102.193:2181 --replication-factor 3 --partitions 1 --topic recsys
+
+e. 查看是否创建成功
+
+> bin/kafka-topics.sh --list --zookeeper localhost:2181
+
+> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
+Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
+ Topic: my-replicated-topic Partition: 0 Leader: 1 Replicas: 1,2,0 Isr: 1,2,0
+
+
+
+f. kafka启动测试
+
+> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
+This is a message
+This is another message
+
+> bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning
+This is a message
+This is another message
+
+g. 注意事项
+
+在开发程序的时候,producer客户端必须要配置上broker的host映射信息,即使你的程序中使用的都是ip地址。
+
+## 项目开发
+
+### 程序部署目录
+
+ /libs
+ * Logback包:logback-classic-1.1.2.jar,logback-core-1.1.2.jar
+ * Kafka包(在kafka安装包lib目录中)
+ /conf
+ * Logback:logback.xml
+
+ /webapps/recsys
+ * index.html
+ /
+ * logcount-1.0.jar
+
+### Spark_Streaming 处理数据
+### HBase 保存数据
+
+创建hbase表
+
+ create ‘recsys_logs’,’f’
+
+服务器端部署.服务器端启动了一个httpserver,该server需要将jar包中的html页面解压出来,所以先解压,后运行程序
+
+ jar xvf recsys-1.0.jar
+
+
+#### 系统运行
+
+客户端
+
+> java -Dlogback.configurationFile=./conf/logback.xml -classpath .:libs/*:logcount-1.0.jar com.wankun.logcount.kafka.TailService dest.log
+
+ 服务端
+
+> spark-submit --class com.wankun.logcount.spark.LogStream --master spark://SparkMaster:7077 logcount-1.0.jar
+
+
+### 注释
+
+
diff --git a/docs/images/architecture.png b/docs/images/architecture.png
new file mode 100644
index 0000000..036c4d8
Binary files /dev/null and b/docs/images/architecture.png differ
diff --git a/docs/日志分析系统.docx b/docs/日志分析系统.docx
new file mode 100644
index 0000000..91fd8e3
Binary files /dev/null and b/docs/日志分析系统.docx differ
diff --git a/docs/架构.ppt b/docs/架构.ppt
new file mode 100644
index 0000000..6ea3b53
Binary files /dev/null and b/docs/架构.ppt differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e2512bc
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,87 @@
+
+ 4.0.0
+
+ com.wankun
+ logcount
+ 1.0
+ jar
+
+ logcount
+ http://maven.apache.org
+
+
+
+ cloudera
+ https://repository.cloudera.com/cloudera/cloudera-repos
+
+
+
+
+ UTF-8
+ 1.1.0-cdh5.2.0
+ 0.98.6-cdh5.2.0
+
+
+
+ jdk.tools
+ jdk.tools
+ 1.7.0_51
+ system
+ ${JAVA_HOME}/lib/tools.jar
+
+
+ ch.qos.logback
+ logback-classic
+ 1.1.2
+
+
+ org.apache.kafka
+ kafka_2.10
+ 0.8.1.1
+
+
+
+ org.apache.spark
+ spark-streaming_2.10
+ ${spark.version}
+
+
+ org.apache.spark
+ spark-streaming-kafka_2.10
+ ${spark.version}
+
+
+
+ org.apache.hbase
+ hbase-client
+ ${hbase.version}
+
+
+ org.apache.hbase
+ hbase-server
+ ${hbase.version}
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.1
+
+ 1.6
+ 1.6
+ UTF-8
+
+
+
+
+
diff --git a/src/main/java/com/wankun/logcount/kafka/MsgSender.java b/src/main/java/com/wankun/logcount/kafka/MsgSender.java
new file mode 100644
index 0000000..e8c1c45
--- /dev/null
+++ b/src/main/java/com/wankun/logcount/kafka/MsgSender.java
@@ -0,0 +1,54 @@
+package com.wankun.logcount.kafka;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+import java.util.concurrent.BlockingQueue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import kafka.javaapi.producer.Producer;
+import kafka.producer.KeyedMessage;
+import kafka.producer.ProducerConfig;
+
+public class MsgSender extends Thread {
+ private final static Logger logger = LoggerFactory.getLogger(MsgSender.class);
+
+ private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+
+ private BlockingQueue queue;
+ private Producer producer;
+
+ public MsgSender(BlockingQueue queue) {
+ this.queue = queue;
+
+ Properties props = new Properties();
+ props.put("metadata.broker.list", "10.10.102.191:9092,10.10.102.192:9092,10.10.102.193:9092");
+ props.put("serializer.class", "kafka.serializer.StringEncoder");
+ // props.put("partitioner.class", "example.producer.SimplePartitioner");
+ props.put("request.required.acks", "1");
+
+ ProducerConfig config = new ProducerConfig(props);
+
+ producer = new Producer(config);
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ String line = queue.take();
+ if (line != null && !line.replace("\n", "").replace("\r", "").equals("")) {
+ String timestamp = sdf.format(new Date());
+ KeyedMessage data = new KeyedMessage("recsys", timestamp, line);
+ logger.debug("sending kv :( {}:{})", timestamp, line);
+ producer.send(data);
+ }
+ } catch (InterruptedException e) {
+ logger.error("kafka producer 消息发送失败", e);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wankun/logcount/kafka/TailLog.java b/src/main/java/com/wankun/logcount/kafka/TailLog.java
new file mode 100644
index 0000000..b013870
--- /dev/null
+++ b/src/main/java/com/wankun/logcount/kafka/TailLog.java
@@ -0,0 +1,132 @@
+package com.wankun.logcount.kafka;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.CharBuffer;
+import java.util.concurrent.BlockingQueue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TailLog extends Thread {
+ private final static Logger logger = LoggerFactory.getLogger(TailLog.class);
+
+ private BlockingQueue queue;
+ private String logname;
+
+ private CharBuffer buf = CharBuffer.allocate(4096);
+
+ // private ByteBuffer buf = ByteBuffer.allocate(4096);
+
+ public TailLog(BlockingQueue queue, String logname) {
+ this.queue = queue;
+ this.logname = logname;
+ }
+
+ @Override
+ public void run() {
+ BufferedReader reader = null;
+ try {
+ // Path logpath=Paths.get(logname);
+ // File posfile =
+ // logpath.getParent().resolve("."+logpath.getFileName()+".pos").toFile();
+ reader = new BufferedReader(new FileReader(new File(logname)));
+
+ long filesize = 0;
+ while (true) {
+ // 判断文件是否已经切换
+ if (filesize > new File(logname).length()) {
+ logger.debug("filesize :{} current system file size :{} . Log file switchover!", filesize,
+ new File(logname).length());
+ try {
+ // 在切换读文件前,读取文件全部内容
+ StringBuilder line = new StringBuilder();
+ while (reader.read(buf) > 0) {
+ buf.flip();
+ synchronized (buf) {
+ // 读buffer 并解析
+ for (int i = 0; i < buf.limit(); i++) {
+ char c = buf.get();
+ line.append(c);
+ if ((c == '\n') || (c == '\r'))
+ if (line.length() > 0) {
+ queue.put(line.toString());
+ line = new StringBuilder();
+ }
+ }
+ }
+ }
+ queue.put(line.toString());
+ buf.clear();
+
+ // 切换读文件
+ if (reader != null)
+ reader.close();
+ reader = new BufferedReader(new FileReader(new File(logname)));
+ } catch (Exception e) {
+ logger.error("文件 {} 不存在", logname, e);
+ Thread.currentThread().sleep(10000);
+ continue;
+ }
+ }
+
+ for (int retrys = 10; retrys > 0; retrys--) {
+ int bufread = reader.read(buf);
+ if (bufread < 0) {
+ if (retrys > 0)
+ Thread.currentThread().sleep(1000);
+ else {
+ // 等待10s后无新数据读出
+ synchronized (buf) {
+ // 等待 cachetime 秒后文件仍未写入
+ buf.flip();
+ char[] dst = new char[buf.length()];
+ buf.get(dst);
+ buf.clear();
+ queue.put(new String(dst));
+ }
+ }
+ } else {
+ filesize = new File(logname).length();
+ retrys = -1;
+
+ buf.flip();
+ synchronized (buf) {
+ // 读buffer 并解析
+ StringBuilder line = new StringBuilder();
+ for (int i = 0; i < buf.limit(); i++) {
+ char c = buf.get();
+ line.append(c);
+ if ((c == '\n') || (c == '\r'))
+ if (line.length() > 0) {
+ queue.put(line.toString());
+ line = new StringBuilder();
+ }
+ }
+ // 接着写不完整的数据
+ buf.compact();
+ if (line.length() > 0) {
+ buf.append(line);
+ }
+ }
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("文件读取失败", e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ logger.error("文件 reader 关闭失败", e);
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wankun/logcount/kafka/TailService.java b/src/main/java/com/wankun/logcount/kafka/TailService.java
new file mode 100644
index 0000000..4017fbd
--- /dev/null
+++ b/src/main/java/com/wankun/logcount/kafka/TailService.java
@@ -0,0 +1,28 @@
+package com.wankun.logcount.kafka;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TailService {
+
+ private final static Logger logger = LoggerFactory.getLogger(TailService.class);
+
+ public static void main(String[] args) {
+ if (args.length < 1) {
+ logger.error("Usage : TailService [logfile]");
+ System.exit(0);
+ }
+
+ BlockingQueue queue = new ArrayBlockingQueue(10000);
+
+ for (String arg : args) {
+ new TailLog(queue, arg).start();
+ }
+
+ new MsgSender(queue).start();
+ }
+
+}
diff --git a/src/main/java/com/wankun/logcount/spark/LogStream.java b/src/main/java/com/wankun/logcount/spark/LogStream.java
new file mode 100644
index 0000000..1c307eb
--- /dev/null
+++ b/src/main/java/com/wankun/logcount/spark/LogStream.java
@@ -0,0 +1,141 @@
+package com.wankun.logcount.spark;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.client.HConnection;
+import org.apache.hadoop.hbase.client.HConnectionManager;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.http.HttpServer2;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.spark.SparkConf;
+import org.apache.spark.api.java.JavaRDD;
+import org.apache.spark.api.java.function.Function;
+import org.apache.spark.streaming.Duration;
+import org.apache.spark.streaming.api.java.JavaDStream;
+import org.apache.spark.streaming.api.java.JavaPairReceiverInputDStream;
+import org.apache.spark.streaming.api.java.JavaStreamingContext;
+import org.apache.spark.streaming.kafka.KafkaUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import scala.Tuple2;
+
+import com.google.common.collect.Maps;
+
+public class LogStream {
+ private final static Logger logger = LoggerFactory.getLogger(LogStream.class);
+
+ private static HConnection connection = null;
+ private static HTableInterface table = null;
+ private static HttpServer2 infoServer = null;
+
+ public static void openHBase(String tablename) throws IOException {
+ Configuration conf = HBaseConfiguration.create();
+ synchronized (HConnection.class) {
+ if (connection == null)
+ connection = HConnectionManager.createConnection(conf);
+ }
+
+ synchronized (HTableInterface.class) {
+ if (table == null) {
+ table = connection.getTable("recsys_logs");
+ }
+ }
+
+ /* start http info server */
+ HttpServer2.Builder builder = new HttpServer2.Builder().setName("recsys").setConf(conf);
+ InetSocketAddress addr = NetUtils.createSocketAddr("0.0.0.0", 8089);
+ builder.addEndpoint(URI.create("http://" + NetUtils.getHostPortString(addr)));
+ infoServer = builder.build();
+
+ infoServer.addServlet("monitor", "/monitor", RecsysLogs.class);
+ infoServer.setAttribute("htable", table);
+ infoServer.setAttribute("conf", conf);
+ infoServer.start();
+ }
+
+ public static void closeHBase() {
+ if (table != null)
+ try {
+ table.close();
+ } catch (IOException e) {
+ logger.error("关闭 table 出错", e);
+ }
+ if (connection != null)
+ try {
+ connection.close();
+ } catch (IOException e) {
+ logger.error("关闭 connection 出错", e);
+ }
+ if (infoServer != null && infoServer.isAlive())
+ try {
+ infoServer.stop();
+ } catch (Exception e) {
+ logger.error("关闭 infoServer 出错", e);
+ }
+ }
+
+ public static void main(String[] args) {
+ // open hbase
+ try {
+ openHBase("logcount");
+ } catch (IOException e) {
+ logger.error("建立HBase 连接失败", e);
+ System.exit(-1);
+ }
+
+ SparkConf conf = new SparkConf().setAppName("recsys log stream");
+ JavaStreamingContext ssc = new JavaStreamingContext(conf, new Duration(1000));
+
+ Map topicMap = Maps.newHashMap();
+ topicMap.put("recsys", 4);
+ JavaPairReceiverInputDStream logstream = KafkaUtils.createStream(ssc,
+ "10.10.102.191:2181,10.10.102.192:2181,10.10.102.193:2181", "recsys_group1", topicMap);
+
+ JavaDStream lines = logstream.map(new Function, String>() {
+ private static final long serialVersionUID = -1801798365843350169L;
+
+ @Override
+ public String call(Tuple2 tuple2) {
+ return tuple2._2();
+ }
+ }).filter(new Function() {
+ private static final long serialVersionUID = 7786877762996470593L;
+
+ @Override
+ public Boolean call(String msg) throws Exception {
+ return msg.indexOf("character service received paramters:") > 0;
+ }
+ });
+
+ // 统计Log中的数据,并保存到HBase中
+ JavaDStream nums = lines.count();
+ nums.foreachRDD(new Function, Void>() {
+
+ private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+
+ @Override
+ public Void call(JavaRDD rdd) throws Exception {
+ Long num = rdd.take(1).get(0);
+ String ts = sdf.format(new Date());
+ Put put = new Put(Bytes.toBytes(ts));
+ put.add(Bytes.toBytes("f"), Bytes.toBytes("nums"), Bytes.toBytes(num));
+ table.put(put);
+ return null;
+ }
+ });
+
+ ssc.start();
+ ssc.awaitTermination();
+ }
+
+}
diff --git a/src/main/java/com/wankun/logcount/spark/RecsysLogs.java b/src/main/java/com/wankun/logcount/spark/RecsysLogs.java
new file mode 100644
index 0000000..cb5b804
--- /dev/null
+++ b/src/main/java/com/wankun/logcount/spark/RecsysLogs.java
@@ -0,0 +1,49 @@
+package com.wankun.logcount.spark;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.filter.PageFilter;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CellUtil;
+
+public class RecsysLogs extends HttpServlet {
+
+ private static final long serialVersionUID = 4289573629015709424L;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ HTableInterface htable = (HTableInterface) getServletContext().getAttribute("htable");
+ Scan scan = new Scan();
+ scan.addColumn(Bytes.toBytes("f"), Bytes.toBytes("nums"));
+ scan.setReversed(true);
+ // scan.setMaxResultSize(20);
+ scan.setFilter(new PageFilter(20));
+ ResultScanner scanner = htable.getScanner(scan);
+ StringBuilder sb = new StringBuilder();
+ for (Result res : scanner) {
+ Cell cell = res.getColumnLatestCell(Bytes.toBytes("f"), Bytes.toBytes("nums"));
+ Long nums = Bytes.toLong(CellUtil.cloneValue(cell));
+ String key = Bytes.toString(CellUtil.cloneRow(cell));
+ sb.append(key + " : " + nums + "\n");
+ }
+ scanner.close();
+
+ resp.getWriter().write(sb.toString());
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ this.doGet(req, resp);
+ }
+
+}
diff --git a/src/main/resources/hbase-site.xml b/src/main/resources/hbase-site.xml
new file mode 100644
index 0000000..1fa2c4f
--- /dev/null
+++ b/src/main/resources/hbase-site.xml
@@ -0,0 +1,214 @@
+
+
+
+
+
+ hbase.cluster.distributed
+ true
+
+
+
+ hbase.rootdir
+ hdfs://dwztgame/hbase
+
+
+
+ dfs.datanode.max.xcievers
+ 40960
+
+
+
+ hbase.zookeeper.quorum
+ node01.dw.ztgame.com:2181,node02.dw.ztgame.com:2181,node03.dw.ztgame.com:2181
+
+
+
+ hbase.regionserver.handler.count
+ 200
+ Count of RPC Server instances spun up on RegionServers
+ Same property is used by the Master for count of master handlers.
+ Default is 10.
+
+
+
+ hbase.regionserver.flushlogentries
+ 500
+ Sync the HLog to HDFS when it has accumulated this many
+ entries. Default 1. Value is checked on every HLog.hflush
+
+
+
+ hbase.regionserver.optionallogflushinterval
+ 2000
+ Sync the HLog to the HDFS after this interval if it has not
+ accumulated enough entries to trigger a sync. Default 1 second. Units:
+ milliseconds.
+
+
+
+ hbase.regionserver.thread.splitcompactcheckfrequency
+ 600000
+ How often a region server runs the split/compaction check.
+
+
+
+ hbase.regions.slop
+ 0
+ Rebalance if any regionserver has average + (average * slop) regions.
+ Default is 0% slop.
+
+
+
+ hbase.server.thread.wakefrequency
+ 5000
+ Time to sleep in between searches for work (in milliseconds).
+ Used as sleep interval by service threads such as log roller.
+
+
+
+ hbase.hregion.memstore.flush.size
+ 134217728
+ Memstore will be flushed to disk if size of the memstore
+ exceeds this number of bytes. Value is checked by a thread that runs
+ every hbase.server.thread.wakefrequency.
+
+
+
+ hbase.hregion.memstore.block.multiplier
+ 6
+
+ Block updates if memstore has hbase.hregion.block.memstore
+ time hbase.hregion.flush.size bytes. Useful preventing
+ runaway memstore during spikes in update traffic. Without an
+ upper-bound, memstore fills such that when it flushes the
+ resultant flush files take a long time to compact or split, or
+ worse, we OOME.
+
+
+
+ hbase.hregion.memstore.mslab.enabled
+ true
+ Experimental: Enables the MemStore-Local Allocation Buffer,
+ a feature which works to prevent heap fragmentation under
+ heavy write loads. This can reduce the frequency of stop-the-world
+ GC pauses on large heaps.
+
+
+
+ hfile.block.cache.size
+ 0.2
+ Percentage of maximum heap (-Xmx setting) to allocate to block cache
+ used by HFile/StoreFile. Default of 0.2 means allocate 20%.
+ Set to 0 to disable.
+
+
+
+ hbase.regionserver.nbreservationblocks
+ 10
+ The number of resevoir blocks of memory release on
+ OOME so we can cleanup properly before server shutdown.
+
+
+
+ hbase.regionserver.global.memstore.upperLimit
+ 0.5
+ Maximum size of all memstores in a region server before new
+ updates are blocked and flushes are forced. Defaults to 40% of heap
+
+
+
+ hbase.regionserver.global.memstore.lowerLimit
+ 0.4
+ When memstores are being forced to flush to make room in
+ memory, keep flushing until we hit this mark. Defaults to 35% of heap.
+ This value equaggl to hbase.regionserver.global.memstore.upperLimit causes
+ the minimum possible flushing to occur when updates are blocked due to
+ memstore limiting.
+
+
+
+ hbase.hregion.max.filesize
+ 2684354560
+
+ Maximum HStoreFile size. If any one of a column families' HStoreFiles has
+ grown to exceed this value, the hosting HRegion is split in two.
+ Default: 256M.
+
+
+
+ hbase.snapshot.enabled
+ true
+
+
+
+ hbase.regionserver.regionSplitLimit
+ 200
+ Limit for the number of regions after which no more region
+ splitting should take place. This is not a hard limit for the number of
+ regions but acts as a guideline for the regionserver to stop splitting after
+ a certain limit. Default is set to MAX_INT; i.e. do not block splitting.
+
+
+
+ hbase.hstore.compactionThreshold
+ 4
+ If more than this number of HStoreFiles in any one HStore
+ (one HStoreFile is written per flush of memstore) then a compaction
+ is run to rewrite all HStoreFiles files as one. Larger numbers
+ put off compaction but when it runs, it takes longer to complete.
+
+
+
+ hbase.hstore.blockingStoreFiles
+ 12
+ If more than this number of StoreFiles in any one Store
+ (one StoreFile is written per flush of MemStore) then updates are
+ blocked for this HRegion until a compaction is completed, or
+ until hbase.hstore.blockingWaitTime has been exceeded.
+
+
+
+ hbase.hstore.compaction.max
+ 6
+ Max number of HStoreFiles to compact per 'minor' compaction.
+
+
+
+ hbase.hregion.majorcompaction
+ 172800000
+ The time (in miliseconds) between 'major' compactions of all
+ HStoreFiles in a region. Default: 1 day.
+ .set to 0 to disable automated major compactions.
+
+
+
+ io.storefile.bloom.enabled
+ true
+
+
+
+ hbase.replication
+ true
+
+
+
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..8dd2893
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+ logs/recsys.log
+
+ logs/recsys.log.%i.bak
+ 1
+ 12
+
+
+ 100MB
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/webapps/recsys/index.html b/src/main/resources/webapps/recsys/index.html
new file mode 100644
index 0000000..f9ba4cf
--- /dev/null
+++ b/src/main/resources/webapps/recsys/index.html
@@ -0,0 +1,11 @@
+
+
+
+ recsys logs 监控系统
+
+
+
+ 欢迎使用recsys logs 监控系统!