我在Mesos上运行Docker的经验

正如在此博客中我所写到的,我想和你分享我如何在一个单集群中使用docker容器来运行分析作业。该技术我们在 Zions 研究的是在 MapR 平台和 MapR-FS 之上运行的 Apache Mesos.我的目标是尝试构建一个无处不在的计算平台。为了分析,我运行Spark和 Myriad (在该领域针对 MapR 和其他的平台需要更多的开发)。Myriad 是我正在用来运行 MapReduce 作业。我同时使用运行于 mesos 之上的 Kafka 和 Storm,与 MapR 文件系统一起使用,或跟当前环境协同使用。

MapR 提供了极大的帮助当其运行 mesos 之上 Docker 容器。一个例子是我运行于 docker 内部的 Hive metastore 服务。因为 Hive metastore 需要一个关系型数据库来持久化表的元数据, 其需要我同时部署一个 MySQL 服务实例。 我在一个基于 Mesos 的 Docker 内通过Marathon来发布该实例而不是通过部署 MySQL 在集群之外的独立服务器上。 由于 MySQL 存储的数据非常重要,我想确认如果容器崩溃或其宿主机死掉,Marathon 可以创建新的容器并接管其离线的所有完好的数据。MapR-FS 的 NFS 功能非常简单将其实现,因为其随机读写的能力和为一个数据库维持负载的高性能。

利用 MapR 文件系统

一个需要我解决的问题是当一个 MySQL 数据库被启用,其需要针对数据库文件的独占访问。我想防止意外启动的另一个 Docker 容器将运行在这些文件之上,这是因为拥有两个实例的 MySQL 访问相同的文件将不是一个好事如果你想你的数据库文件保持一致性。所以我与 Ted Dunning 和 Keys Botzum 在 MapR 对其进行了深入的了解,我请教他们,“我如何使用一个锁?” 尽管 MapR NFS 在传统的 Unix 角度不支持锁定, MapR 支持通过创建目录和新建文件的文件系统标准的启用锁定。

使用他们的建议,我写了一个脚本实现了锁定模式其允许可靠的持久性数据存储。其意味着别人也可以从中获得好处,所以我将该脚本分享于此。

这里分为两部分,第一部分是, “我想在该文件上行使用一个锁并且我想其为独占式”。这里并不支持,但另一方面, MapR 支持语义上的创建一个目录并唯一可能的创建该目录,这也是我再该脚本中所使用的,我想能够创建一些东西我的 Docker 容器可以发现并且说, “有些人同时使用该数据,我需要关闭。” 我的脚本防止有两个不同实例的 MySQL 或 Hive Metastore 运行于我的集群之上,但我仍然有能力在我的集群的任意节点运行 MySQL .

这里对其运行在哪没有任何限制。 Mesos 社区尝试去解决该问题的一种方式是将数据持久化到不同的框架上-所以你可以使用该数据块-并且其在未来的版本中被包含。但 MapR 拥有高性能的文件系统在我的所有节点上都可用,因此我想更好的利用它。

为Docker容器处理文件系统锁而写的我的代码

基本上讲,这段代码运行如一个垫片,我调用该代码而不是启用我期望在Mesos中直接启用的任何进程,该代码会检测每个我设定的特定目录。例如, 如果是 MySQL 或 Minecraft Docker 容器, 其会针对容器检测一个单独的地址。 我的 Minecraft 服务器在 MapR-FS中有一个地址;这正是其检测并决定如果它可以在该目录上拥用一个独占锁并运行。如果它不能够这样做-它发现有些进程也对该目录上锁,其会知 晓它不能够运行并关掉该容器。这就保证了我不会有多于一个的 相同类型的 Docker 容器。我不想两个 Minecraft 服务器运行,因为他们将工作在相同的数据之上,因而导致文件损坏。

这里是我为 Docker 容器处理文件系统锁而写的代码:

#!/bin/bash

#The location the lock will be attempted in

LOCKROOT="/minecraft/lock"

LOCKDIRNAME="lock"

LOCKFILENAME="mylock.lck"

#This is the command to run if we get the lock.

RUNCMD="./start.sh"

#Number of seconds to consider the Lock stale, this could be application dependent.

LOCKTIMEOUT=60

SLEEPLOOP=30

LOCKDIR=${LOCKROOT}/${LOCKDIRNAME}

LOCKFILE=${LOCKDIR}/${LOCKFILENAME}

if mkdir "${LOCKDIR}" &>/dev/null; then

echo "No Lockdir. Our lock"

# This means we created the dir!

# The lock is ours

# Run a sleep loop that puts the file in the directory

while true; do date +%s > $LOCKFILE ; sleep $SLEEPLOOP; done &

#Now run the real shell scrip

$RUNCMD

else

#Pause to allow another lock to start

sleep 1

if [ -e "$LOCKFILE" ]; then

echo "lock dir and lock file Checking Stats"

CURTIME= date +%s
FILETIME= cat $LOCKFILE

DIFFTIME=$(($CURTIME-$FILETIME))

echo "Filetime $FILETIME"

echo "Curtime $CURTIME"

echo "Difftime $DIFFTIME"

if [ "$DIFFTIME" -gt "$LOCKTIMEOUT" ]; then

echo "Time is greater then Timeout We are taking Lock"

# We should take the lock! First we remove the current directory because we want to be atomic

rm -rf $LOCKDIR

if mkdir "${LOCKDIR}" &>/dev/null; then

while true; do date +%s > $LOCKFILE ; sleep $SLEEPLOOP; done &

$RUNCMD

else

echo "Cannot Establish Lock file"

exit 1

fi

else

# The lock is not ours.

echo "Cannot Estblish Lock file - Active "

exit 1

fi

else

# We get to be the locker. However, we need to delete the directory and recreate so we can be all atomic about

rm -rf $LOCKDIR

if mkdir "${LOCKDIR}" &>/dev/null; then

while true; do date +%s > $LOCKFILE ; sleep $SLEEPLOOP; done &

$RUNCMD

else

echo "Cannot Establish Lock file - Issue"

exit 1

fi

fi

fi

# End

在 MapR 上运行开源软件:支持的非常好

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d070e6aefc4f8fd1b3656bf098e25e1e.html