转载请注明源地址http://www.cnblogs.com/dongxiao-yang/p/4910059.html

zookeeper具有自动清除快照日志和事务日志的工能,可以在配置文件设置autopurge.purgeInterval来实现,问题是这个属性的时间单位是小时,

有些情况下,一小时的日志过大(比如把事务日志放到内存),需要手动删除,所以需要研究下zk删除日志文件的源码。

清理日志主类:org.apache.zookeeper.server.PurgeTxnLog,包含如下几个静态工具方法

static void printUsage(){

System.out.println("PurgeTxnLog dataLogDir [snapDir] -n count");

System.out.println("\tdataLogDir -- path to the txn log directory");

System.out.println("\tsnapDir -- path to the snapshot directory");

System.out.println("\tcount -- the number of old snaps/logs you want to keep");

System.exit(1);

}

常见的帮助方法,告诉使用者参数的传入顺序,其中snapdir参数为可选,假如两种日志配置在同一个路径下,只传一个路径参数就好。

main方法,没什么好说的,只是解析参数。

public static void purge(File dataDir, File snapDir, int num) throws IOException {

if (num < 3) {

throw new IllegalArgumentException("count should be greater than 3");

}

FileTxnSnapLog txnLog = new FileTxnSnapLog(dataDir, snapDir);

List<File> snaps = txnLog.findNRecentSnapshots(num);

retainNRecentSnapshots(txnLog, snaps);

}

删除文件的主方法,主要分两个部分

1:txnLog.findNRecentSnapshots(num);

找到需要保留的文件

主要逻辑代码为

public List<File> findNRecentSnapshots(int n) throws IOException {

List<File> files = Util.sortDataDir(snapDir.listFiles(), "snapshot", false);

int i = 0;

List<File> list = new ArrayList<File>();

for (File f: files) {

if (i==n)

break;

i++;

list.add(f);

}

return list;

}

private static class DataDirFileComparator

implements Comparator<File>, Serializable

{

private static final long serialVersionUID = -2648639884525140318L;

private String prefix;

private boolean ascending;

public DataDirFileComparator(String prefix, boolean ascending) {

this.prefix = prefix;

this.ascending = ascending;

}

public int compare(File o1, File o2) {

long z1 = Util.getZxidFromName(o1.getName(), prefix);

long z2 = Util.getZxidFromName(o2.getName(), prefix);

int result = z1 < z2 ? -1 : (z1 > z2 ? 1 : 0);

return ascending ? result : -result;

}

}

/**

* Sort the list of files. Recency as determined by the version component

* of the file name.

*

* @param files array of files

* @param prefix files not matching this prefix are assumed to have a

* version = -1)

* @param ascending true sorted in ascending order, false results in

* descending order

* @return sorted input files

*/

public static List<File> sortDataDir(File[] files, String prefix, boolean ascending)

{

if(files==null)

return new ArrayList<File>(0);

List<File> filelist = Arrays.asList(files);

Collections.sort(filelist, new DataDirFileComparator(prefix, ascending));

return filelist;

}

2 删除文件

// VisibleForTesting

static void retainNRecentSnapshots(FileTxnSnapLog txnLog, List<File> snaps) {

// found any valid recent snapshots?

if (snaps.size() == 0)

return;

File snapShot = snaps.get(snaps.size() -1);

int ii=snaps.size() -1;

System.out.println(ii);

final long leastZxidToBeRetain = Util.getZxidFromName(

snapShot.getName(), PREFIX_SNAPSHOT);

class MyFileFilter implements FileFilter{

private final String prefix;

MyFileFilter(String prefix){

this.prefix=prefix;

}

public boolean accept(File f){

if(!f.getName().startsWith(prefix + "."))

return false;

long fZxid = Util.getZxidFromName(f.getName(), prefix);

if (fZxid >= leastZxidToBeRetain) {

return false;

}

return true;

}

}

// add all non-excluded log files

List<File> files = new ArrayList<File>(Arrays.asList(txnLog

.getDataDir().listFiles(new MyFileFilter(PREFIX_LOG))));

// add all non-excluded snapshot files to the deletion list

files.addAll(Arrays.asList(txnLog.getSnapDir().listFiles(

new MyFileFilter(PREFIX_SNAPSHOT))));

// remove the old files

for(File f: files)

{

System.out.println("Removing file: "+

DateFormat.getDateTimeInstance().format(f.lastModified())+

"\t"+f.getPath());

if(!f.delete()){

System.err.println("Failed to remove "+f.getPath());

}

}

}

Util.getZxidFromName工具方法代码

public static long getZxidFromName(String name, String prefix) {

long zxid = -1;

String nameParts[] = name.split("\\.");

if (nameParts.length == 2 && nameParts[0].equals(prefix)) {

try {

zxid = Long.parseLong(nameParts[1], 16);

} catch (NumberFormatException e) {

}

}

return zxid;

}

zookeeper 删除snapshot和transaction log的源码解读的更多相关文章

  1. HttpClient 4.3连接池参数配置及源码解读

    目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB-&g ...

  2. go语言nsq源码解读八 http.go、http_server.go

    这篇讲另两个文件http.go.http_server.go,这两个文件和第六讲go语言nsq源码解读六 tcp.go.tcp_server.go里的两个文件是相对应的.那两个文件用于处理tcp请求, ...

  3. ThreadLocal源码解读

    1. 背景 ThreadLocal源码解读,网上面早已经泛滥了,大多比较浅,甚至有的连基本原理都说的很有问题,包括百度搜索出来的第一篇高访问量博文,说ThreadLocal内部有个map,键为线程对象 ...

  4. 从koa-session源码解读session本质

    前言 Session,又称为"会话控制",存储特定用户会话所需的属性及配置信息.存于服务器,在整个用户会话中一直存在. 然而: session 到底是什么? session 是存在 ...

  5. ScheduledThreadPoolExecutor源码解读

    1. 背景 在之前的博文--ThreadPoolExecutor源码解读已经对ThreadPoolExecutor的实现原理与源码进行了分析.ScheduledExecutorService也是我们在 ...

  6. HttpClient4.3 连接池参数配置及源码解读

    目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB-&g ...

  7. etcd学习(6)-etcd实现raft源码解读

    etcd中raft实现源码解读 前言 raft实现 看下etcd中的raftexample newRaftNode startRaft serveChannels 领导者选举 启动并初始化node节点 ...

  8. Vue 源码解读(3)—— 响应式原理

    前言 上一篇文章 Vue 源码解读(2)-- Vue 初始化过程 详细讲解了 Vue 的初始化过程,明白了 new Vue(options) 都做了什么,其中关于 数据响应式 的实现用一句话简单的带过 ...

  9. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

随机推荐

  1. JavaScript Array(数组) 对象

    更多实例 合并两个数组 - concat() 合并三个数组 - concat() 用数组的元素组成字符串 - join() 删除数组的最后一个元素 - pop() 数组的末尾添加新的元素 - push ...

  2. php输出echo、print、print_r、printf、sprintf、var_dump的区别比较

    本篇文章是对php输出echo.print.print_r.printf.sprintf.var_dump的区别进行了详细的分析介绍,需要的朋友参考下     用.net开发已经5年了,最近突然想接触 ...

  3. hadoop 分片与分块,map task和reduce task的理解

    分块:Block HDFS存储系统中,引入了文件系统的分块概念(block),块是存储的最小单位,HDFS定义其大小为64MB.与单磁盘文件系统相似,存储在 HDFS上的文件均存储为多个块,不同的是, ...

  4. Chess---->简单命令框象棋(人VS人)

    简单粗暴,直接先上代码: ChessBoard.h:  1 #ifndef CHESBOARD_H  2 #include<iostream>  3 #include<string& ...

  5. Aspnet MVC 异步调用

    一个简图来描述下Aspnet MVC下的异步调用 { request } / \/ -------ISS------- > work thread | \ | \ route - aysn co ...

  6. IIC 概述之1

    概述: I²C 是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or "eye-two-cee" , 它是一 ...

  7. coroutine协程

    如果你接触过lua这种小巧的脚本语言,你就会经常接触到一个叫做协程的神奇概念.大多数脚本语言都有对协程不同程度的支持.但是大多编译语言,如C/C++,根本就不知道这样的东西存在.当然也很多人研究如何在 ...

  8. 大众点评试水O2O新模式:实体店试穿,扫描二维码付款 现场取货

    在餐饮美食行业取得不错的成绩之后,大众点评将触角延伸到了线下的传统商铺,开始涉足线下商品的 O2O 团购.和传统的线上下单,线下消费的 O2O 模式不同.大众点评的 O2O 团购用户,可在店内试穿后通 ...

  9. SpringMvc配置 导致实事务失效

    SpringMVC回归MVC本质,简简单单的Restful式函数,没有任何基类之后,应该是传统Request-Response框架中最好用的了. Tips 1.事务失效的惨案 Spring MVC最打 ...

  10. Linux Shell脚本Ldd命令原理及使用方法

    1.首先ldd不是一个可执行程序,而只是一个shell脚本2.ldd能够显示可执行模块的dependency,其原理是通过设置一系列的环境变量如下:LD_TRACE_LOADED_OBJECTS.LD ...