更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群

当使用 Notebook 的项目日渐增加时,火山引擎 DataLeap 研发团队发现运行中的 PaaS 服务实在太多了,之前的架构有如下缺点:

  1. 部署麻烦。全量升级 JupyterLab 较为痛苦。尽管有升级脚本,但是通过 API 操作升级服务,可能由于镜像构建失败等原因,会造成卡单现象。

  2. JupyterLab 需要不断的根据用户增长(项目增长)进行扩容,一旦预先启动好的资源池不够,就会存在新项目里有用户打开 Notebook,需要经历整个 JupyterLab 服务创建、环境拉起的流程,速度较慢,影响体验。

  3. 运维困难。当用户 JupyterLab 可能出现问题,为了找到对应的 JupyterLab,我们需要先根据项目对应到 JupyterHub user,然后根据 user 找到 JupyterHub 记录的服务 id,再去 PaaS 平台找服务,进 webshell。

  4. 当然,还有资源的浪费。虽然每个实例很小(1c1g),但是数量很多;有些项目并不总是在使用 Notebook,但 JupyterLab 依然运行。

  5. 稳定性存在问题。一方面,JupyterHub 是一个单点,升级需要先起后停,挂了有风险。另一方面,EG 入流量经过特定负载均衡策略,本身是为了使 JupyterLab 固定往一个 EG 请求。在 EG 升级时,JupyterLab 请求的终端会随之改变,极端情况下有可能造成 Kernel 启动多次的情况。

基于简化运维成本、降低架构复杂性,以及提高用户体验的考虑,2021 上半年,火山引擎 DataLeap 研发团队对整体架构进行了一次改良。在新的架构中,火山引擎 DataLeap 研发团队主要做了以下改进,大致简化为下图:

  1. 移除 JupyterHub,将 JupyterLab 改为多实例无状态常驻服务,并实现对接火山引擎 DataLeap 的多用户鉴权。

  2. 改造原本落在 JupyterLab 本地的数据存储,包括用户自定义配置、Session 维护和代码文件读写。

  3. EG 支持持久化 Kernel,将 Kernel 远程环境元信息持久化在远端存储(MySQL)上,使其重启时可以重连,且 JupyterLab 可以知道某个 Kernel 需要通过哪个 EG 连接。

(图:火山引擎 DataLeap 下改进版 Notebook 整体架构)

单用户的 Jupyter Notebook / JupyterLab 的鉴权相对简单(实际上 JupyterLab 直接复用了 Jupyter Notebook 的这套代码)。例如,使用默认命令启动时,会自动生成一个 token,同时自动拉起浏览器。有了 token,就可以任意地访问这个 Notebook。

事实上,JupyterHub 也是起到了维护 Token 的作用。前端会发起一个获取 Token 的 API 请求,再拿着获取的 Token 请求通过 JupyterHub proxy 到真实的 Notebook 实例。

(图:前: JupyterHub 提供的 auth 能力;后:实现了 auth 功能的 JupyterLab)

最后,由于所有用户会共享同一组 JupyterLab,火山引擎 DataLeap 研发团队还需要禁止一些接口的调用,以保证系统的安全。最典型的接口包括关闭服务(Shutdown),以及修改配置等。后续 Notebook 所需的配置,转由前端保存在浏览器内。

Jupyter Notebook 使用 File Managerhttps://github.com/jupyter-server/jupyter_server/blob/main/jupyter_server/services/contents/filemanager.py)管理 Contents 相关读写,原生行为是将代码存储在本地,多个服务实例之间无法共享同一份代码,而且迁移时可能造成代码丢失。

为了避免代码丢失,火山引擎 DataLeap 研发团队的做法是,把代码按项目分别存储在 OSS 上并直接读写,同时解决了一些由于代码文件元信息丢失,并发编辑导致的其他问题。

(图:按项目分别持久化代码到 OSS)

Notebook 使用 Session 管理用户到 Kernel 的连接,例如前端通过 POST /session 接口启动 Kernel,GET /session 查看当前运行中的 Kernel。在 Session 处理方面,原生的 Notebook 使用了原生的 sqlite(in memory),见代码https://github.com/jupyter-server/jupyter_server/blob/main/jupyter_server/services/sessions/sessionmanager.py)。

(图:Session 表)

Kernel Gateway 在启动 Kernel 时,记录了关于 Kernel 的一些元信息,包括启动参数、连接 Kernel 使用的 IP/Port 等。有了这些信息,当一个 Kernel Gateway 重启且 Remote Kernel 不关闭,就有办法重新连接上。 原本这些信息默认在内存 dict 中维护,开源仓库中有一套存储在本地文件的方案;基于这套方案,火山引擎 DataLeap 研发团队扩展了自研的存储到 MySQL 的方案。

(图:EG 访问流程示意图)

当 EG 服务本身重启或者升级时,会在进程退出之前去清除接管信息。当页面继续访问时,JupyterLab 服务将会随机分发相应请求,由其它的 EG 服务继续接管。

架构升级简化后,整套火山引擎 DataLeap 下的 Notebook 服务的稳定性获得了极大的提升。由于实现了用户无感知的升级,不仅提升了用户的使用体验,运维的成本也同时降低了。

点击跳转 大数据研发治理DataLeap 了解更多

火山引擎 DataLeap 下 Notebook 系列文章三:架构升级详解的更多相关文章

  1. springboot系列(三)配置文件详解

    目录 properties 文件 1.语法 2.优先级 3.自定义数据配置 4.获取自定义数据配置 1.通过prefix获取 yml文件 1.语法 2.优先级 3.自定义数据配置. 4.获取自定义数据 ...

  2. 深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(二)---配置简介(mybatis源码篇)>我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根 ...

  3. 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...

  4. SpringBoot系列(十二)过滤器配置详解

    SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...

  5. 火山引擎 DataLeap:3 个关键步骤,复制字节跳动一站式数据治理经验

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理. ...

  6. 如何又快又好实现 Catalog 系统搜索能力?火山引擎 DataLeap 这样做

      摘要 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理.资产.安全等全套数据中台建设,降低工作成本和数据维护成本.挖掘数据价 ...

  7. 火山引擎 DataLeap:揭秘字节跳动数据血缘架构演进之路

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维 ...

  8. 火山引擎 A/B 测试产品——DataTester 私有化架构分享

    作为一款面向 ToB 市场的产品--火山引擎A/B测试(DataTester)为了满足客户对数据安全.合规问题等需求,探索私有化部署是产品无法绕开的一条路. 在面向 ToB 客户私有化的实际落地中,火 ...

  9. Hexo系列(三) 常用命令详解

    Hexo 框架可以帮助我们快速创建一个属于自己的博客网站,熟悉 Hexo 框架提供的命令有利于我们管理博客 1.hexo init hexo init 命令用于初始化本地文件夹为网站的根目录 $ he ...

  10. elasticsearch系列三:索引详解(分词器、文档管理、路由详解(集群))

    一.分词器 1. 认识分词器  1.1 Analyzer   分析器 在ES中一个Analyzer 由下面三种组件组合而成: character filter :字符过滤器,对文本进行字符过滤处理,如 ...

随机推荐

  1. Redis7新特性简介及十大数据类型

    Redis是基于内存的K-V键值对内存数据库 浅谈Redis7新特性 主要是自身底层性能和资源利用率上的提高和优化. 多AOF文件支持 config命令增强 限制客户端内存使用 listpack紧凑列 ...

  2. Unity学习笔记--基础

    基础 3D数学 Mathf函数库 print(Mathf.PI); print(Mathf.Abs(-10)); print(Mathf.CeilToInt(1.2f));//向上取整 print(M ...

  3. JUC并发编程学习笔记(十)线程池(重点)

    线程池(重点) 线程池:三大方法.七大参数.四种拒绝策略 池化技术 程序的运行,本质:占用系统的资源!优化资源的使用!-> 池化技术(线程池.连接池.对象池......):创建和销毁十分消耗资源 ...

  4. sizeof结构体数组指针和sizeof数组指针的区别

    请思考一下 以下代码输出的 sizeof 分别是多少? #include <stdio.h> typedef struct { char name[100]; unsigned char ...

  5. JavaSE中的一些面试题

    list与Set区别 List 和 Set 是 Java 集合中两个重要的接口,它们在数据存储.数据查找.数据操作等方面有以下几个不同点: 1. 数据存储方式不同:List 是一个有序的 Collec ...

  6. 🔥🔥Java开发者的Python快速进修指南:面向对象基础

    当我深入学习了面向对象编程之后,我首先感受到的是代码编写的自由度大幅提升.不同于Java中严格的结构和约束,Python在面向对象的实现中展现出更加灵活和自由的特性.它使用了一些独特的关键字,如sel ...

  7. 生产实践:Redis与Mysql的数据强一致性方案

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 数据库和Redis如何保持强一致性,这篇文章告诉你 目的 Redis和Msql来保持数据同步,并且强一致,以此来提高对应接 ...

  8. 总结(3)--- 知识总结(内存管理、线程阻塞、GIL锁)

    一.Python中是如何进行内存管理的? 垃圾回收:Python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值.对Python而言,对象的类型和内存都是在运行时确定的 ...

  9. ZooKeeper论文阅读笔记

    ZooKeeper论文传送门 介绍 ZooKeeper 是一个开源的分布式协调服务,它提供了高可用性和一致性的数据管理和协调功能.它被设计用于构建可靠的分布式系统,并提供了一组简单而强大的 wait- ...

  10. 掌握HarmonyOS框架的ArkTs如何管理和共享状态数据

    本文分享自华为云社区<深入理解ArkTs中的AppStorage和LocalStorage>,作者:柠檬味拥抱 . ARKTS(Ark TypeScript)是HarmonyOS应用框架的 ...