zookeeper 删除snapshot和transaction log的源码解读

转载请注明源地址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;

}

时间: 2024-10-31 08:44:30

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

Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现

如果Spark的部署方式选择Standalone,一个采用Master/Slaves的典型架构,那么Master是有SPOF(单点故障,Single Point of Failure).Spark可以选用ZooKeeper来实现HA. ZooKeeper提供了一个Leader Election机制,利用这个机制可以保证虽然集群存在多个Master但是只有一个是Active的,其他的都是Standby,当Active的Master出现故障时,另外的一个Standby Master会被选举出来.由于

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

目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB->服务端处理请求,查询数据并返回),发现原本的HttpClient连接池中的一些参数配置可能存在问题,如defaultMaxPerRoute.一些timeout时间的设置等,虽不能确定是由于此连接池导致接口查询慢,但确实存在可优化的地方,故花时间做一些研究.本文主要涉及HttpClient连接池.请求的参数

Tomcat源码解读:我们发起的HTTP请求如何到达Servlet的

在上一节中,了解了Tomcat服务器启动的整个过程,现在来了解一下Tomcat如何接收到HTTP请求,并将请求送达至Servlet,Servlet处理后,响应信息又是如何返回给浏览器的呢?这两个问题是接下来要研究的课题,本节先研究第一个问题. 了解一点点网络知识的人,都会知道TCP连接通信是基于Socket的,上一节也有提到这点.通过上一节的说明,可以了解到Tomcat服务器在内部已经使用Endpoint类封装了Socket. 本篇会包含大量的源码解读说,由于篇幅原因,就将源码折叠起来,如果想了

OpenCV2马拉松第27圈——SIFT论文,原理及源码解读

计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/28913101 简介 SIFT特征描述子是David G. Lowe 在2004年的ijcv会议上发表的论文中提出来的,论文名为<<Distinctive Image Featuresfrom Scale-Invariant Keypoints>>.这是一个很强大的算法,主要用于图像配准和物体识别等领域,但是其计算量相比也比较大,性价

AFNetworking 3.0 源码解读 总结

终于写完了 AFNetworking 的源码解读.这一过程耗时数天.当我回过头又重头到尾的读了一篇,又有所收获.不禁让我想起了当初上学时的种种情景.我们应该对知识进行反复的记忆和理解.下边是我总结的 AFNetworking 中能够学到的知识点. 1.枚举(enum) 使用原则:当满足一个有限的并具有统一主题的集合的时候,我们就考虑使用枚举.这在很多框架中都验证了这个原则.最重要的是能够增加程序的可读性. 示例代码: /** * 网络类型 (需要封装为一个自己的枚举) */ typedef NS

vue源码解读预热-0

vueJS的源码解读 vue源码总共包含约一万行代码量(包括注释)特别感谢作者Evan You开放的源代码,访问地址为Github 代码整体介绍与函数介绍预览 代码模块分析 代码整体思路 总体的分析 从图片中可以看出的为采用IIFE(Immediately-Invoked Function Expression)立即执行的函数表达式的形式进行的代码的编写 常见的几种插件方式: (function(,){}(,))或(function(,){})(,)或!function(){}()等等,其中必有

jdk1.8.0_45源码解读——HashMap的实现

jdk1.8.0_45源码解读——HashMap的实现 一.HashMap概述 HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作.存储的是<key,value>对的映射,允许多个null值和一个null键.但此类不保证映射的顺序,特别是它不保证该顺序恒久不变.  除了HashMap是非同步以及允许使用null外,HashMap 类与 Hashtable大致相同. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能.迭代col

15、Spark Streaming源码解读之No Receivers彻底思考

在前几期文章里讲了带Receiver的Spark Streaming 应用的相关源码解读,但是现在开发Spark Streaming的应用越来越多的采用No Receivers(Direct Approach)的方式,No Receiver的方式的优势: 1. 更强的控制自由度 2. 语义一致性 其实No Receivers的方式更符合我们读取数据,操作数据的思路的.因为Spark 本身是一个计算框架,他底层会有数据来源,如果没有Receivers,我们直接操作数据来源,这其实是一种更自然的方式

jdk1.8.0_45源码解读——Set接口和AbstractSet抽象类的实现

jdk1.8.0_45源码解读——Set接口和AbstractSet抽象类的实现 一. Set架构 如上图: (01) Set 是继承于Collection的接口.它是一个不允许有重复元素的集合.(02) AbstractSet 是一个抽象类,它继承于AbstractCollection.AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利.(03) HastSet 和 TreeSet 是Set的两个实现类.        HashSet依赖于HashMa