Giter Site home page Giter Site logo

galaxy's Issues

galaxy账户,权限,quota管理

需求背景

目前galaxy资源分配只是针对job,分配的原则是用户通过sdk提交多少资源需求就满足多少,可能会导致一些无关紧要的job占用过多资源,导致重要的任务无法获取资源。所以需要一个人维度的资源分配原则。

账户

账户是为了明确当前对galaxy进行操作的用户

需要对galaxy改造的地方

从目前使用来看,最容易最好的方式是在控制台里面加入账户功能

  • console接入单点登陆系统(针对公司内部),或采用自身的账户系统(django自带)
  • sdk接口访问需要进行改为通过console http接口(优先级不高)

权限

权限主要针对多用户情况,避免一个用户对其他用户的job进行相关操作(比如删除)

job 权限控制

大致流程,用户创建自己的权限组(简单分两个类型只读,读写),然后在这个权限组里面操作job,还可将其他人加入权限组

主要需求

  • console 加入权限,目前先加入job权限,分为只读与读写

quota

quota主要控制单个权限组对资源的使用,避免单个用户组超额使用资源

Ubuntu 14.04编译错误

g++ -o agent_unittest -Wl,-rpath-link ./thirdparty/boost_1_57_0/stage/lib src/test_agent/test_collector_engine.o src/test_agent/test_container.o src/test_agent/test_container_property.o src/test_agent/test_container_status.o src/test_agent/test_cpu_subsystem.o src/test_agent/test_dict_file.o src/test_agent/test_file_input_stream.o src/test_agent/test_freezer_subsystem.o src/test_agent/test_memory_subsystem.o src/test_agent/test_mounter.o src/test_agent/test_netcls_subsystem.o src/test_agent/test_output_stream_file.o src/test_agent/test_process.o src/test_agent/test_symlink_volum.o src/test_agent/test_tcpthrot_subsystem.o src/test_agent/test_tmpfs_volum.o src/test_agent/test_volum_group.o src/test_agent/unit_test.o src/agent/cgroup/blkio_subsystem.o src/agent/cgroup/cgroup.o src/agent/cgroup/cgroup_collector.o src/agent/cgroup/cpu_subsystem.o src/agent/cgroup/cpuacct_subsystem.o src/agent/cgroup/freezer_subsystem.o src/agent/cgroup/memory_subsystem.o src/agent/cgroup/netcls_subsystem.o src/agent/cgroup/subsystem.o src/agent/cgroup/subsystem_factory.o src/agent/cgroup/tcp_throt_subsystem.o src/agent/collector/collector_engine.o src/agent/container/container.o src/agent/container/container_gc.o src/agent/container/container_manager.o src/agent/container/container_property.o src/agent/container/container_stage.o src/agent/container/container_status.o src/agent/container/icontainer.o src/agent/container/process.o src/agent/container/serializer.o src/agent/container/volum_container.o src/agent/health/healthy_checker.o src/agent/resource/cpu_resource.o src/agent/resource/resource_manager.o src/agent/resource/volum_resource.o src/agent/util/dict_file.o src/agent/util/input_stream_file.o src/agent/util/output_stream_file.o src/agent/util/path_tree.o src/agent/util/user.o src/agent/util/util.o src/agent/volum/bind_volum.o src/agent/volum/mounter.o src/agent/volum/origin_volum.o src/agent/volum/symlink_volum.o src/agent/volum/tmpfs_volum.o src/agent/volum/volum.o src/agent/volum/volum_collector.o src/agent/volum/volum_group.o src/agent/agent_flags.o src/protocol/galaxy.pb.o src/protocol/agent.pb.o -Lthirdparty/lib -Lthirdparty/boost_1_57_0/stage/lib -lins_sdk -lsofa-pbrpc -lprotobuf -lsnappy -lglog -lgflags -ltcmalloc -lunwind -lpthread -lz -lrt -lboost_filesystem -lgtest -lcommon -lleveldb
thirdparty/lib/libleveldb.a(table_builder.o): In function leveldb::port::Snappy_Compress(char const*, unsigned long, std::string*)': table_builder.cc:(.text._ZN7leveldb4port15Snappy_CompressEPKcmPSs[_ZN7leveldb4port15Snappy_CompressEPKcmPSs]+0x1c): undefined reference to snappy::MaxCompressedLength(unsigned long)'
table_builder.cc:(.text._ZN7leveldb4port15Snappy_CompressEPKcmPSs[_ZN7leveldb4port15Snappy_CompressEPKcmPSs]+0x56): undefined reference to snappy::RawCompress(char const*, unsigned long, char*, unsigned long*)' thirdparty/lib/libleveldb.a(format.o): In function leveldb::port::Snappy_GetUncompressedLength(char const*, unsigned long, unsigned long*)':
format.cc:(.text._ZN7leveldb4port28Snappy_GetUncompressedLengthEPKcmPm[_ZN7leveldb4port28Snappy_GetUncompressedLengthEPKcmPm]+0x27): undefined reference to snappy::GetUncompressedLength(char const*, unsigned long, unsigned long*)' thirdparty/lib/libleveldb.a(format.o): In function leveldb::port::Snappy_Uncompress(char const*, unsigned long, char*)':
format.cc:(.text._ZN7leveldb4port17Snappy_UncompressEPKcmPc[_ZN7leveldb4port17Snappy_UncompressEPKcmPc]+0x27): undefined reference to `snappy::RawUncompress(char const*, unsigned long, char*)'
collect2: error: ld returned 1 exit status
scons: *** [agent_unittest] Error 1
scons: building terminated because of errors.

scheduler.cc中存在Segmentation Fault

scheduler.cc:140的delete操作会触发Segmentation Fault,该错误使用quick_test脚本运行时,因其试图删除一个空指针而触发。此时调用栈的情况为:
#0 in baidu::galaxy::Scheduler::ScheduleScaleUp at src/scheduler/scheduler.cc:140
#1 in baidu::galaxy::SchedulerIO::Loop at src/scheduler/scheduler_io.cc:96
#2 in main at src/scheduler/scheduler_main.cc:26

qq 20150810104652

更新 Package 设计

Motvation

目前galaxy采用双buffer方式进行package更新操作时,需要手动按步长调整更新实例数,所以需要一个自动化的方式更新package

实现需要考虑问题列表

  • 更新并发控制
  • 暂停点,更新多个实例后暂停(暂不考虑)
  • 回滚
  • job meta 版本管理 ,这个与回滚有关系

实现设计

需要添加的变量

master 维护一个job维度的 version通过修改version 来上线或者回滚;
task 添加一个 updating 状态 参与调度;并发控制可以使用上线并发控制参数

实现说明

master修改job version ,与 agent heart 返回的job version 做对比查看是否一致,如果不一致,task进入updating状态,并记录(并发控制和避免重复发送更新命令),异步发送更新命令给agent.

Galaxy 3.0重构计划

Galaxy 3.0设计

背景

Galaxy3.0是对Galaxy2.0的重构,主要解决以下问题:

  1. 容器管理和服务管理紧耦合:服务的升级和启停都伴随容器的销毁和调度;
  2. 没有磁盘管理,只能管理home盘;
  3. 不支持用户quota和记账;
  4. 机器管理功能缺失;
  5. Naming功能可用性低;
  6. Trace功能不完善;

系统架构

    Galaxy3.0架构上分为2层: 资源管理层和服务管理层,每层都是主从式架构  
    1. 资源管理层由ResMan(Resource Manager)和Agent构成  
    2. 服务管理层由AppMaster和AppWorker构成, 每个服务有自己的AppMaster进程


                   Naming _                       Job_A1          Job_A2
                            \                       |               |
                             \__ AppMaster_A <--> AppWorker_A1   AppWorker_A2
                                     |              |               |
     +----------------------------------------------------------------------+
     |  ResMan  <--------------->  Agent1         Agent2      Agent3 ....
     +----------------------------------------------------------------------+
                                     |              |               |
                                 AppMaster_B <--> AppWorker_B1   AppWorker_B2
                                                    |               |
                                                  Job_B1          Job_B2

上面的图有点抽象,可以举一个不太恰当的例子。

Galaxy就是一个五星级酒店,每天都有大量游客组团入住和离开。
ResMan就是大堂经理,负责按照每个团的人数、房间需求来分配房间,以及记账结账;
Agent就是酒店服务员,确保房间就绪,以及游客离开后打扫等;
AppMaster是旅游团团长,确保每个游客不掉队,以及组织一些集体活动;
AppWorker就是小导游,负责把游客引导到房间,并且跟进游客的状态,汇报给团长;

调度逻辑

用户提交的Job内容主要是两部分:资源需求 + 程序启停

  1. 一个Job提交后,就持久化到Nexus中。 ResMan只关心资源需求部分,ResMan命令有资源的Agent创建容器: 1个Master容器 + N个Worker容器;
  2. Agent在Master容器启动AppMaster进程, Agent在Worker容器启动AppWorker进程; AppMaster进程把自己的地址记录在Nexus上;
  3. Master容器的调度需要在有特殊Tag的机器上,这样确保AppMaster的稳定性;
  4. AppWorker进程发RPC请求AppMaster进程, AppMaster分配任务给AppWorker执行, AppWorker反馈任务执行状态给AppMaster;(执行的任务包括:下载程序包、启动程序、停止程序、Load词典、更新程序版本等)

容错

  1. ResMan有备份,通过Nexus抢锁来Standby;
  2. Agent跟踪每个容器的状态汇报给ResMan,当容器个数不够或者不符合ResMan的要求时,就需要调度:创建或删除容器;
  3. AppWorker负责跟踪用户程序的状态,当用户程序coredump、异常退出或者被cgroup kill后,反馈状态给AppMaster,AppMaster根据指定策略命令AppWorker是否再次拉起。
  4. AppMaster如果异常挂掉,或者所在机器挂掉,ResMan会销毁此容器,并且在其他Agent上创建一个Master容器;

服务发现

  1. SDK通过Nexus发现指定的Job的AppMaster地址;
  2. SDK请求AppMaster,发现每个Job实例的地址和当前的服务状态;
  3. AppMaster会定时同步服务地址和状态到第三方Naming系统(如BNS,ZK等);

服务更新

  1. SDK通过Nexus发现指定的Job的AppMaster地址;
  2. SDK请求AppMaster, AppMaster将服务更新命令传播给AppWorker, AppWorker将更新状态反馈给AppMaster;
  3. AppWorker和AppMaster的通信方式是Pull的方式,因此AppMaster可以根据当前的情况来决定部署的暂停和步长控制;
  4. 服务的更新都在容器内进行,不涉及到容器的销毁和创建

系统依赖

  1. Nexus作为寻址和元信息保存
  2. MDT作为用户日志的Trace系统
  3. Sofa-PbRPC作为通信基础库

job支持one_task_per_host属性

motivation

存储系统调度 #79 一般在一台机器只运行一个实例,为了满足这个需求,在job属性里面添加一个one_task_per_host属性

具体实现

控制台部分创建job表单添加一个单host运行一个实例属性,默认值为false,传递到galaxy master.
master的调度器在为job选择部署机器时,如果job 的 one_task_per_host为true时,会通过当前任务里面的agents属性判断机器是否已经部署了这个job

优先级抢占调度设计

背景

目前在galaxy 调度器 采用FCFS(First come ,First served)策略,当chunkserver,tabletserver 出现故障或者升级时释放出资源,此时上层计算任务先到达调度器,可用占用释放出的资源,而后到的chunkserver,tabletserver无法重新部署到以前的机器上面,会导致chunkserver丢副本,tabletserver丢ssd cache

优先级分类

对galaxy服务的应用可以大致抽象3个优先级层次出来

  • 对硬件资源有需要的chunkserver,tabletserver storage_service 100
  • 常驻内存只对cpu 内存有需求的 normal_service 70
  • 只运行一段时间的 batch_task 20

抢占策略

采用悲观抢占方式,每次抢占都要全局最优,同一类优先级服务不抢占,只抢占下一层级资源,但享受优先调度,

实现

目前只实现对批处理任务抢占#262

任务启动失败也显示running

在没有root权限的机器上运行sandbox, 提交任务,由于无法创建galaxy帐号,任务启动失败,但是listtask显示都在running状态。

使用tag标记agent方式支持存储系统调度

调度系统需要解决以下问题

  • 存储系统是有状态应用,运行过程中会产生持久化数据,不能丢失
  • 单机运行一个实例
  • 需要访问多个磁盘(磁盘管理暂时不支持)

调度系统对存储系统要求

  • 支持重启,并且能够从持久化数据恢复

具体实现

用tag标记agent

使用tag标记agent,存储系统调度到特定标签机器上面,凡是这类标签的agent都支持重新启动存储系统,继续复用以前的持久化数据,标签解决存储系统迁移问题。但是目前agent运行task具有workspace概念,workspace里面保存task的包和日志,workspace是没法复用,如果存储系统在workspace做了数据持久化 就没法做迁移。
master需要支持

  • 指定机器标记tag
  • 在调度器里面加上筛选tag逻辑

实现需要考虑问题,Agent 与 Tag的关系需要持久化存储,用于master恢复时使用.
数据流

当前子卡片

job需要添加一个属性,one_task_per_host #88
galaxy master 支持 tag标记agent #89
控制台页面支持 用户标记agent

内核2.6.32_1-15-0-0 blkio子系统测试

motivation

希望找到一种隔离 workspace io 的子系统,避免单个应用占用过多io,影响其他workspace

blkio子系统介绍

blkio 全称block io controller,支持io控制策略

  • 基于CFQ按照权重分配时间片,提供给进行读写时间
  • 控制io上限

控制io上限测试

test script

#!/usr/bin/env sh
CONTAINER=/cgroups/blkio/ioupper-test
test -e $CONTAINER || mkdir -p $CONTAINER

# read and write with 1m limit
echo "8:32 1048576" > $CONTAINER/blkio.throttle.read_bps_device
echo "8:32 1048576" > $CONTAINER/blkio.throttle.write_bps_device
dd if=/dev/zero of=bigfile bs=1M count=1024
echo $! > $CONTAINER/tasks
# lanuch read test
dd if=bigfile of=/dev/null bs=10k count=1024 iflag=direct
# lanuch write test
dd if=/dev/zero of=testfile bs=10k count=1024 oflag=direct

output

1024+0 records in
1024+0 records out
10485760 bytes (10 MB) copied, 14.8745 s, 705 kB/s
1024+0 records in
1024+0 records out
10485760 bytes (10 MB) copied, 11.0007 s, 953 kB/s

上面使用direct io进行测试,能够限制住 io, 去掉flag测试
输出

1024+0 records in
1024+0 records out
10485760 bytes (10 MB) copied, 0.00359568 s, 2.9 GB/s
1024+0 records in
1024+0 records out
10485760 bytes (10 MB) copied, 0.0117846 s, 890 MB/s

上面说明 blkio目前只适用同步io,对读写buffer没法限制

目前没有完善的io隔离方式,我们能不能把io高的应用部署在其申请的磁盘上面,这样不会影响其他应用。

references

https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt
https://www.kernel.org/doc/Documentation/devices.txt

batch类型任务调度

现有的任务类型调度都是按照优先占满整机资源调度的,batch类型任务,本身优先低一些,可以考虑占用些资源碎片。

master的数据持久化

需求:1. 记录snapshot,以及更改log
2. 数据维度包含jobMeta, taskInstanceMeta,以及SlaveMeta,不包含实时可检测的状态信息
问题:task_raw中程序包应该转储到管理程序包的存储介质中,task_raw只包含地址
设计:1. 数据存储在分布式存储中(leveldb/zk)
2. 设计snapshot数据结果与log结构,log结构包含3种更新(1. job更新,2. instance更新,3. slave信息更新),且log包含时间戳以及持续递增的logid;snapshot结构,最后一次的log id,时间戳,以及对应的(job/instance/slave)的内存状态
3. snapshot的生成可通过从上一个snapshot到现在的log生成
4. snapshot生成后可清理之前的log数据
内容:1. master内存数据结构转pb,方便序列化
2. task instance状态持久化,(实际部署位置变更)
3. job meta信息持久化
4. slave的注册状态持久化

DISK管理

Motivation

目前galaxy agent把所有应用放在home目下面,如果多个应用打日志或者出core,会占用很多磁盘空间,可能因为一个应用导致整个home目录打满,使其他应用没法正常运行,所以需要单个磁盘进行quota分配;还有目前所有agent上面disk命名不规范,比如有的机器以disk0开始,有的以disk1开始,还有机器磁盘个数也不一致,所以需要解决不同机器磁盘统一化问题

整块disk分配管理

job 创建时,可以选择自己需要哪些块disk

需要考虑问题

一块disk的分配的生命周期,一块disk被占用后,什么时候释放,能够使用的是

  • 和job生命周期一样,实例部署好后被job占用,job删除掉后释放disk
  • 后台人工释放disk

基于tag disk管理

最简单实现方式

给每个agent标记tag,每个agent上面包含特定的元数据例如:

tag1 -> [agent1:disk1,agent2:disk2,disk1,agent3:disk1,disk2,disk3]

这种实现方式 不考虑disk生命周期,大家约定好使用那块磁盘
优点:实现简单,master需要修改tag管理,agent启动需要注入环境变量,让应用获取能用磁盘,然后替换配置问题,同一个实例能够在异构环境下运行
缺点:tag 元数据管理成本高,task需要根据环境变量来知道自己能够使用哪些磁盘,无法解决disk权限问题,需要手动添加磁盘权限

基于chroot和软连方式 disk管理

例如job 需要/home/disk1, /home/disk2

cd task_workspace
chown galaxy:galaxy /home/disk0
chown galaxy:galaxy /home/disk1
mkdir -p home/disk1 home/disk2
mount -o bind /home/disk0 home/disk1
mount -o bind /home/disk1 home/disk2
chroot . "command"

这种实现方式 不考虑disk生命周期,大家约定好使用那块磁盘
优点:task可以写死配置,可以解决disk权限问题
缺点:针对存储系统,需要记录软连命令,记录真正物理disk和用户需要路径对应关系,实现需要解决chroot问题,master需要持久化agent上面磁盘和挂载磁盘的对应关系

开了内存软限的Pod无法收集到已用内存

例如, ./galaxy pods -j 查看的时候,看不见FileServer的CPU和内存的使用情况,都是0。

另外, 之前设置软限用的是memory.soft_limit_in_bytes , 正确的方法是设置memory.excess_mode=1

部署增加黑名单功能

有的机器硬件有故障,是不可能部署成功的,这时候不应该再分配任务给这个机器

build4internal编译不过

目录结构:
work/ps/a/galaxy

sh build4internal.sh各种报错,有java的依赖,还有ins的
“make: *** No rule to make target ins/libins_sdk.a', needed byscheduler'. Stop.”

cpu soft limit逻辑

cpu soft limit

相关结构
调度单元
struct SchedulerCell {
cpu_limit; ----- 用户提交quota限制量
cpu_extra; ----- 动态调度提供的cpu量,可能为负数,表示cpu空闲较大
cpu_extra_need; ---- 动态计算的cpu extra需求量
cpu_usages ---- cpu历史使用情况
};
调度器相关参数
scheduler_interval --- 调度周期
low_threshold ---- 允许最低cpu idle使用情况
high_threshold ---- 允许最高cpu idle使用情况
max_cpu_usage_history_len ---- 最大采集长度,使用率采集长度满足最大值才可进行cpu_extra_need计算
整体计算步骤分为三步

  • 计算单个调度单元的cpu需求量
    首先根据历史cpu使用情况计算avg_idle_cores
    计算单个调度单元的cpu_extra_need,此处考虑如下:
  • 对于cpu_extra < 0(表示cpu quota因为idle问题被降低),该种情况下,如平均idle量> high_threshold, 则每次降低,max_cpu_deinc_delta(0.5个核心),如果平均idle量<low_threshold,则直接恢复cpu_extra至0,来保证用户业务的quota
  • 而对于cpu_extra>0(表示使用率较高,多分配了空闲cpu),该情况下,如平均idle量>high_threshold, 则每次降低值,直到能够保证idle计算满足[low_threshold, high_threshold).如idle量>high_threshold, 则每次增加一个空闲核心
  • 调整整体调度单元的cpu需求量
    由于第一步的cpu_extra_need均根据单个调度单元的实际使用情况计算,会出现需求量大于实际机器拥有情况,需要根据整体情况进行互相调整
    根据第一步的计算结果,将整体结果分成cpu_extra >=0,cpu_extra<0的两个队列,优先级算cpu_extra<0的队列,如果整体需求量无法满足,则通过打压cpu_extra>=0队列任务的cpu_extra_need,如果依然无法满足,则通过削减该队列中cpu_extra,来满足quota需求。cpu_extra会选择最大的,来削减,尽量降低影响面。
  • 实际执行调度生效

后面待升级的点:

  1. 支持用户设置frozen_time, 在启动阶段可保证一定时间不进行cpu打压
  2. 支持用户自定义threshold

部署增加超时检查功能

有的机器有各种环境问题,例如wget的二进制不正确,磁盘挂载失败等,部署会一直卡到deploying状态,需要增加一个超时检查,超过时间的,及时更换agent部署

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.