zookeeperСерия статей по анализу исходного кода:
Оригинальный блог, чисто ручной стук, источник для перепечатки указывайте, спасибо!
Поскольку мы собираемся изучать исходный код, как эффективно изучить исходный код? Ответ — журналы трассировки. Говоря оzookeeperЖурнал, редактор считает это очень важным, если лог-файла нет, то позжеzookeeperОбработка транзакций в основном неиграбельна. Поэтому я будуzookeeperЖурнал размещен во второй части серии анализа исходного кода, также в возможности запускаzookeeperНа основе анализа журнала.
один,zookeeperтип журнала
zookeeperСуществует два типа журналов, а именно:
- 1. Журнал транзакций
log - 2. Журнал моментальных снимков
snapshot
事务日志 :Как следует из названия, он используется для хранения соответствующей информации о выполнении транзакции, такой какzxid,cxidЖдать. Что касается того, чтоzookeeperдела, которые будут рассмотрены в следующей статье.
快照日志 : ``zookeeperДанные узла данных выполняются в памяти.Конечно, данные, хранящиеся в памяти, не могут быть бесконечными, а содержимое узлов данных изменяется динамически, поэтомуzookeeperОбеспечьте механизм сохранения выигрышных узлов данных время от времени,zookeeperбудет хранить узлы данных в памятиDataTreeпоследовательно записываться на диск, формируя таким образом наш журнал моментальных снимков.
существуетzookeeperВ процессе отладки исходного кода, таких как журнал запуска сервера, журнал запуска клиента и соответствующие журналы запроса, потому чтоzookeeperиспользоватьlog4jсделать журнал печати, так чтоlog4jдолжен быть найден в пути к классамlog4j.propertiesфайл, если файл не найден во время запуска, будет сообщено об ошибке следующим образом:
log4j:WARN No appenders could be found for logger (org.apache.log4j.jmx.HierarchyDynamicMBean).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Следовательно, это должно бытьlog4j.propertiesв classpath, то для одиозногоantПроект, где путь к классам? Я тоже не знаю, поэтому прямоeclipseЩелкните правой кнопкой мыши проектBuild Path->Configure build pathНайдите путь к классам как%baseDir%\src\java\main, как показано ниже:
Так будетconfв каталогеlog4j.propertiesСкопируйте копию в каталог выше.
два,zookeeperвизуализация журнала
сказано вышеzookeeperСуществует два типа журналов, но, к сожалению, вы не можете просмотреть вышеуказанные журналы напрямую, потому что все они сохраняются в двоичном формате. ПроверитьzookeeperИсходный код также может быть известен,zookeeperВывод журнала теперьFileTxnLog.javaдокументappend()метод следующим образом:
// 写日志文件,采用log. + 哈希值的命名形式保存文件
logFileWrite = new File(logDir, ("log." + Long.toHexString(hdr.getZxid())));
// 文件输出流
fos = new FileOutputStream(logFileWrite);
// 采用BufferedOutputStream包裹fos成缓冲输出流
logStream=new BufferedOutputStream(fos);
// 这是重点,这里采用org.apache.jute.BinaryOutputArchive二进制构件对logStream进行包裹,输出二进制数据
oa = BinaryOutputArchive.getArchive(logStream);
Соответствующие файлы файловой системы следующие:
Поскольку это двоичный файл журнала, он должен быть искажен, когда мы открываем файл напрямую! Как это сделать? Ниже представлены два метода, оба из которых основаны наzookeeperкоторый предоставилLogFormatter.javaКласс инструмента для достижения.
- 1. В
eclipseОткройте класс, а затем запустите классmainВ то же время вы можете указать путь к файлу журнала, который хотите просмотреть. - 2. Использование командной строки
java -classpath xxx.jar org.apache.zookeeper.server.LogFormatter logFilePathвид в виде
Первый способ:
Предположим, что мой путь к хранилищу файла журналаE:\\resources\\zookeeper-3.4.11\\conf\\log\\version-2\\log.1, когда я вeclipseвбегаетmainметод, вы можете установить входящие параметры, как показано ниже:
Затем вы можете вывести журнал в консоль.Вывод выглядит следующим образом:
ZooKeeper Transactional Log File with dbid 0 txnlog format version 2
18-4-30 下午08时39分23秒 session 0x100022b44190000 cxid 0x0 zxid 0x1 createSession 30000
18-4-30 下午08时39分55秒 session 0x100022b44190000 cxid 0x0 zxid 0x2 closeSession null
EOF reached after 2 txns.
Второй способ:
- 1. Создайте новый временный каталог в любом каталоге и назовите его небрежно
logSee,будуslf4j-api-1.6.1.jarа такжеzookeeper-3.4.11.jarПоместите два файла в этот каталог, затем откройте командную строку и выполнитеjava -classpath .;slf4j-api-1.6.1.jar;zookeeper-3.4.11.jar org.apache.zookeeper.server.LogFormatter E:\\resources\\zookeeper-3.4.11\\conf\\log\\version-2\\log.1
двое из нихjarИспользуйте точку с запятой между пакетами;разделители вместо двоеточий,org.apache.zookeeper.server.LogFormatterвыражатьLogFormatter.javaполное имя пути (即包全名+类名),E:\\resources\\zookeeper-3.4.11\\conf\\log\\version-2\\log.1Указывает файл журнала, который вы хотите просмотреть.
Результат выглядит следующим образом:
три,zookeeperМеханизм очистки журнала
zookeeperЭто хранение лога в виде файла на диске, со временем файлов на диске становится все больше.zookeeperПредоставляет механизм для периодической очистки файлов журналов и моментальных снимков.
QuorumPeerMain.javaдаzookeeperстартовый класс, вzookeeperсоздастDatadirCleanupManagerобъект для выполнения задач по очистке данных,DatadirCleanupManagerОн будет решать, следует ли выполнять очистку и как часто выполнять очистку в соответствии с конфигурацией вашего файла конфигурации.Основной принцип заключается в использованииJDKизTimerРеализация таймера, далее будет проанализирован механизм его реализации с точки зрения исходного кода:
Первый взглядQuorumPeerMainкласс, в которомinitializeAndRun()Когда метод выполняется,DatadirCleanupManagerобъект и будетzoo.cfgВ этот объект передается соответствующая конфигурация конфигурационного файла, а исходный код выглядит следующим образом:
protected void initializeAndRun(String[] args)
throws ConfigException, IOException
{
QuorumPeerConfig config = new QuorumPeerConfig();
if (args.length == 1) {
config.parse(args[0]);
}
// 启动数据目录清理定时任务,传递的参数有数据目录DataDir,日志目录LogDir,以及快照保留数量count,默认>3,最后一个是每个多长时间进行清理
DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config
.getDataDir(), config.getDataLogDir(), config
.getSnapRetainCount(), config.getPurgeInterval());
purgeMgr.start();
if (args.length == 1 && config.servers.size() > 0) {
runFromConfig(config);
} else {
LOG.warn("Either no config or no quorum defined in config, running "
+ " in standalone mode");
// there is only server in the quorum -- run as standalone
ZooKeeperServerMain.main(args);
}
}
вы можете найти его в файле конфигурацииzoo.cfgДобавьте в файл две конфигурации, которыеautopurge.snapRetainCountа такжеautopurge.snapRetainCount.autopurge.purgeIntervalПросто установите, сколько часов нужно очистить. а такжеautopurge.snapRetainCountустановить, сколько оставить快照文件snapshot, все предыдущие удаляются.
Небольшая проблема с производительностью заключается в том, что обычноzookeeperОн работает в кластере, и бизнес будет относительно загружен. Если чистка выполняется каждый раз, это неизбежно повлияет на производительность. Мы зададимся вопросом, есть ли способ выполнить операцию очистки, когда кластер не занят, например, в 12 часов каждую ночь. Но, к сожалению,zookeeperСоответствующая реализация не предусмотрена,zookeeperиспользоватьTimerспособ достижения, а не что-то вродеquartz,Springпредоставить то же самоеcronКонфигурация выражения. Но заметьте, это не означаетTimerНе удается добиться выполнения указанного времени, но сказатьzookeeperЭто не сбылось. потому чтоquartz,SpringНижний слой все еще используетсяTimerа такжеExecutorsЧтобы добиться этого!
посмотри сноваDatadirCleanupManagerизstart()метод:
public void start() {
if (PurgeTaskStatus.STARTED == purgeTaskStatus) {
LOG.warn("Purge task is already running.");
return;
}
// Don't schedule the purge task with zero or negative purge interval.
if (purgeInterval <= 0) {
LOG.info("Purge task is not scheduled.");
return;
}
// 创建TIMER
timer = new Timer("PurgeTask", true);
// 创建定时任务
TimerTask task = new PurgeTask(dataLogDir, snapDir, snapRetainCount);
// 每隔多少小时执行
timer.scheduleAtFixedRate(task, 0, TimeUnit.HOURS.toMillis(purgeInterval));
purgeTaskStatus = PurgeTaskStatus.STARTED;
}
Теперь принцип ясен с первого взгляда, анализ исходного кода лога здесь первым, и вы закончили его читать, и это здорово! Добро пожаловать, чтобы оставить сообщение в области комментариев и много общаться!