暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

说一下 OB 的自启动方式

271

OB 是个单进程软件,启动方式特别简单。OB 又往往是以集群形式运行,机器可能会有点多。有些客户希望如果 OB 集群有服务器重启了,能自动将 OB 进程拉起来。这类客户通常是 OB 社区版用户 和早期 OB 企业版客户。

OB 企业版部署的时候 OCP 会自动在 OB 主机上部署一个拉起 observer 和 obproxy 进程的脚本(放在 rc.local 文件里调用),加上 OB 企业版客户很多都有专门的驻场运维。所以可能企业版客户都没想过有这个需求或问题(因为已经做好了或者有人默默的在做了)。OB 社区版就没有这个便利了。

OB 社区版推出的时候,部署是一个难题,所以推出了 obd 这个自动化部署工具(从使用体验上看借鉴了 TiDB 的部署 tiup )。这类工具使用特点就是先要写配置文件,文件里面很多参数需要修改。如果不修改用默认值跑,大概率是跑不成功的。原因是客户环境跟默认设置差别很大。有些人会觉得这是 OB 问题,可能因为这类用户喜欢简单的开箱即用的东西。对此,我也略感无奈。数据库这个东西怎么可能就是一个简单的东西呢,有些企业还要把核心业务跑在上面。
其实 OB 手动部署也不是很复杂,不管是单节点、还是集群部署,也是要准备相关目录和参数,然后拉起进程,再做一个初始化。OBD 只是把这个过程自动化做了。有些人开始部署 OB 就失败了,多是跟参数配置不当、资源不够有关。各种调整后还是会部署成功的。只是总结起来该花的精力一点都没少。那些目录、参数还是要去搞清楚的。

OB 部署成功后,下次启动的方式确实是简单, 启动二进制文件 observer 即可。比如:/home/admin/oceanbase/bin/observer 。不过这个也是看起来简单,实际还是有一些重要注意事项。
首先在哪个用户下运行这个。这个取决于前面部署到哪个用户下了。企业版都是运行在用户 admin 下(注意只是名字叫 admin ,并不是表示用户是一个 administrator 账户,有名无实😄)。OB 社区版用户使用 OBD 往往一不小心就把数据库部署到 root 用户下了。传统数据库资深 DBA 看到这个,都会有种感觉:不专业。有哪个重要的数据库是在跑在 root 用户下的?最多就是 root 用户下一个启动进程拉起一个 非 root 用户的子进程。这个子进程就是数据库的工作进程。不过现状如此,当你看到一个 OB 环境的时候,如果要拉起 OB 进程,那还是去看一下软件目录、数据文件的目录 owner 是哪个用户。用对应的用户去拉起这个进程。即使它错用了 root 用户,那也就将错就错用 root 用户去拉起 OB 进程吧。
第二在哪个目录下拉起这个进程。虽然上面给的二进制目录是绝对路径,也并不表示在任意目录下执行都能拉起 OB 进程。因为这个进程要读取当前目录下的配置文件目录(目录 etc),要写进程 PID(目录 run),要写进程运行日志(目录 log)。所以这个进程拉起的时候必须在软件 HOME 目录(企业版客户默认是 home/admin/oceanbase)。社区版自定义,默认的配置文件是 root/observer 。如果 HOME 放到这里了,不用 root 启动都没办法了。所以,最万无一失的启动命令是下面这种:
    su - admin
    cd /home/admin/oceanbase && bin/observer
    有兴趣的朋友可以想一下为什么我用 &&  ,以及为什么后面用相对路径。

    OB 社区版从 4.0 后已经推出了 OCP 开源版,这个非常接近 OB 企业版的部署和运维了,强烈推荐用这个部署。已经上线了老的 OB 社区版集群,也可以通过部署 OCP 社区版去接管。接管成功后,就不要再用 OBD 去管理 OB 社区版集群了。

    OBD 自动化运维思路是通过将参数写到配置文件里去实现集群的管理。当 OB 上线后会面临一些新的挑战。如节点资源规格扩容;租户资源扩容或缩容、集群扩容或缩容、节点替换;OB 备集群/备租户部署、OB 备份和还原等。当客户把越来越多的业务放到 OB 上后,对 OB 运维提出的要求自然就会越来越多,这些远不是 OBD 用配置文件加自动化能应付的了。所以 OB 要具备的能力不可能是简单的,否则面对海量数据的运维就捉襟见肘无能为力了。

    OBD 启动和停止 OB 集群是很方便,不过用起来要谨慎。一个生产 OB 集群上线后基本上就不可能去停了。即使是要做机房搬迁,客户往往也是选择在线搬迁方案。除非那个业务实在不重要,停机搬迁。所以对于一个在运行中的业务 OB 集群,OBD 一个命令就给停了,甚至给销毁掉了(destroy),这是很大的风险。加上如果数据库碰到 BUG ,不停还能勉强使用,一停再启动,就要等很久并且可能还启动不成功。OB 读写原理是 LSMTree,增量在内存中。在没有合并甚至转储前,近期产生的大量业务写数据还在内存没有落盘持久化(生成新版本)。这个时候把 OB 进程停了再拉起,它是需要更多时间去恢复的。

    所以 OB 的启动时间相比 MySQL、ORACLE 的启动时间可能会更长。ORACLE 其实也类似,高峰期重启 ORACLE ,恢复时间也是分钟级别的(有很多事务日志要前滚和回滚)。

    所以生产上的 OB 集群,是不轻易的去停止,或者至少不是同时停。一个三副本的 OB 集群,如果要重启,严谨的做法是先合并;然后切主;然后重启某个 ZONE下的 OB 进程;然后再切主;再重启下一个 ZONE 下的 OB 进程。有很多步骤,OCP 运维 OB 的时候就是一步步这么做的。当然 OBD 重启集群的时候也可以这么做。只是,如果这个过程有异常,用户能干预的很少。特别是 DBA 如果不熟悉 OB 进程的手动启动和停止方法以及原理时,面对 OBD 报错会不知所措。

    所以用 OBD 或 OCP 运维 OB 的前提是都要知道手动运维 OB 的方法,然后发挥 OBD 或 OCP 的自动化特性。从使用门槛上,OCP 要低于 OBD。


    再回到 OB 进程的自启动。设置 OB 进程随主机启动后自启动这个是合理的。尽管我更倾向于手动去启动 OB 进程。不过如果主机是掉电了,机房驻场能做的就是启动主机,它并不懂如何去启动数据库。这个时候等 DBA 响应去启动 OB 进程,会浪费不少时间。所以设置为自启动能节省不少恢复时间。
    在实现方式上,OB 论坛上有用户咨询的是写一个 systemd 服务文件,在服务文件里调用 OBD 命令去启停 OB 集群。这个想法是好的,但是实现方式我认为是不对的。
    systemd 服务管理的是linux 本机服务,作用范围应该仅限于本机。OBD 的启停是操作一个 OB 集群,这个 OB 集群的节点并不一定在本机。这么做的结果就是本机如果重启了,会自动调用 OBD 启动一个本来就已经启动的集群。在生产上这个也是错误操作,甚至有点危险。即使 OBD 控制的是本机的集群,也完全不需要这样去实现(理由看后面)。
    所以,OB进程的自启动应该是在 OB 集群服务器节点上去配置。OB 企业版是利用主机的 rc.local 文件,在里面调用一个 OB 启动脚本。详情参考 OB 官网:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000210133 。这个脚本里会做一些定制性检查。
    企业版的这个方式也没问题,社区版我更推荐用 systemd 服务去管理。这样毕竟可以管理这个服务(start/stop/restart)。当然跟前面一样,不要频繁的去 restart 等。好处是这个服务只是管理本机的 OB 进程。
    systemd 服务文件如下:
      [root@server061 ~]# cat etc/systemd/system/observer.service
      [Unit]
      Description=observer systemd service
      After=network.target


      [Service]
      Type=forking
      User=admin
      Environment="LD_LIBRARY_PATH=/home/admin/oceanbase/lib"
      WorkingDirectory=/home/admin/oceanbase
      ExecStart=/home/admin/oceanbase/bin/observer
      ExecStartPost=/bin/sleep 1
      ExecStop=/usr/bin/kill -9 $MAINPID
      ExecStopPost=/bin/sleep 3
      [Install]
      WantedBy=multi-user.target

      在使用这个脚本之前,先在 OB 机器上把 observer 进程杀掉。

        kill -9 `pidof observer`
        sleep 3
        ps -ef|grep observer |grep -v grep

        之所以 sleep 一下,是生产环境,杀一个进程,是需要点时间。

        然后就可以使用 systemd 服务来管理 observer 启动。

          [root@server061 ~]# systemctl start observer
          [root@server061 ~]# systemctl status observer
          ● observer.service - observer systemd service
          Loaded: loaded (/etc/systemd/system/observer.service; enabled; vendor preset: disabled)
          Active: active (running) since Sat 2024-06-22 08:59:35 CST; 7s ago
          Process: 10587 ExecStopPost=/bin/sleep 3 (code=exited, status=0/SUCCESS)
          Process: 10584 ExecStop=/usr/bin/kill -9 $MAINPID (code=exited, status=0/SUCCESS)
          Process: 10689 ExecStartPost=/bin/sleep 1 (code=exited, status=0/SUCCESS)
          Process: 10679 ExecStart=/home/admin/oceanbase/bin/observer (code=exited, status=0/SUCCESS)
          Main PID: 10688 (observer)
          Tasks: 65
          Memory: 191.1M
          CGroup: system.slice/observer.service
          └─10688 home/admin/oceanbase/bin/observer


          Jun 22 08:59:34 server061 systemd[1]: Starting observer systemd service...
          Jun 22 08:59:35 server061 systemd[1]: Started observer systemd service.
          [root@server061 ~]# ps -ef|grep observer
          admin 10688 1 8 08:59 ? 00:00:01 home/admin/oceanbase/bin/observer
          root 10920 2040 0 08:59 pts/2 00:00:00 grep --color=auto observer
          停止 observer 进程。

          [root@server061 ~]# systemctl stop observer
          [root@server061 ~]# ps -ef|grep observer
          root 11805 2040 0 09:00 pts/2 00:00:00 grep --color=auto observer

          将这个服务设置为 自启动模式。



            [root@server062 ~]# systemctl enable observer
            Created symlink from /etc/systemd/system/multi-user.target.wants/observer.service to /etc/systemd/system/observer.service.



            这个脚本我用企业版测试了一下是可以的。社区版用户需要调整脚本中的 user 和 workingdirectory 等。不过我对 systemd 服务文件的理解并不深,有可能这个脚本文件写的有隐患。如果有懂这个的或者发现有问题的,欢迎留言指点我一下。或者点开文末“阅读原文”到 OB 论坛上交流。谢谢!


            更多阅读

            文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论