Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提升系统的启动速度。systemd 和 ubuntu 的 upstart 是竞争对手,预计会取代 UpStart,实际上在做者写做本文时,已经有消息称 Ubuntu 也将采用 systemd 做为其标准的系统初始化系统。html
Systemd 的不少概念来源于苹果 Mac OS 操做系统上的 launchd,不过 launchd 专用于苹果系统,所以长期未能得到应有的普遍关注。Systemd 借鉴了不少 launchd 的思想,它的重要特性以下:linux
Systemd 是一个"新来的",Linux 上的不少应用程序并无来得及为它作相应的改变。和 UpStart 同样,systemd 引入了新的配置方式,对应用程序的开发也有一些新的要求。若是 systemd 想替代目前正在运行的初始化系统,就必须和现有程序兼容。任何一个 Linux 发行版都很难为了采用 systemd 而在短期内将全部的服务代码都修改一遍。ubuntu
Systemd 提供了和 Sysvinit 以及 LSB initscripts 兼容的特性。系统中已经存在的服务和进程无需修改。这下降了系统向 systemd 迁移的成本,使得 systemd 替换现有初始化系统成为可能。安全
Systemd 提供了比 UpStart 更激进的并行启动能力,采用了 socket / D-Bus activation 等技术启动服务。一个显而易见的结果就是:更快的启动速度。服务器
为了减小系统启动时间,systemd 的目标是:网络
尽量启动更少的进程并发
尽量将更多进程并行启动socket
一样地,UpStart 也试图实现这两个目标。UpStart 采用事件驱动机制,服务能够暂不启动,当须要的时候才经过事件触发其启动,这符合第一个设计目标;此外,不相干的服务能够并行启动,这也实现了第二个目标。ide
下面的图形演示了 UpStart 相对于 SysVInit 在并发启动这个方面的改进:高并发
假设有 7 个不一样的启动项目, 好比 JobA、Job B 等等。在 SysVInit 中,每个启动项目都由一个独立的脚本负责,它们由 sysVinit 顺序地,串行地调用。所以总的启动时间为 T1+T2+T3+T4+T5+T6+T7。其中一些任务有依赖关系,好比 A,B,C,D。
而 Job E 和 F 却和 A,B,C,D 无关。这种状况下,UpStart 可以并发地运行任务{E,F,(A,B,C,D)},使得总的启动时间减小为 T1+T2+T3。
这无疑增长了系统启动的并行性,从而提升了系统启动速度。可是在 UpStart 中,有依赖关系的服务仍是必须前后启动。好比任务 A,B,(C,D)由于存在依赖关系,因此在这个局部,仍是串行执行。
让咱们例举一些例子, Avahi 服务须要 D-Bus 提供的功能,所以 Avahi 的启动依赖于 D-Bus,UpStart 中,Avahi 必须等到 D-Bus 启动就绪以后才开始启动。相似的,livirtd 和 X11 都须要 HAL 服务先启动,而全部这些服务都须要 syslog 服务记录日志,所以它们都必须等待 syslog 服务先启动起来。然而 httpd 和他们都没有关系,所以 httpd 能够和 Avahi 等服务并发启动。
Systemd 可以更进一步提升并发性,即使对于那些 UpStart 认为存在相互依赖而必须串行的服务,好比 Avahi 和 D-Bus 也能够并发启动。从而实现以下图所示的并发启动过程:
全部的任务都同时并发执行,总的启动时间被进一步下降为 T1。
可见 systemd 比 UpStart 更进一步提升了并行启动能力,极大地加速了系统启动时间。
当 sysvinit 系统初始化的时候,它会将全部可能用到的后台服务进程所有启动运行。而且系统必须等待全部的服务都启动就绪以后,才容许用户登陆。这种作法有两个缺点:首先是启动时间过长;其次是系统资源浪费。
某些服务极可能在很长一段时间内,甚至整个服务器运行期间都没有被使用过。好比 CUPS,打印服务在多数服务器上不多被真正使用到。您可能没有想到,在不少服务器上 SSHD 也是不多被真正访问到的。花费在启动这些服务上的时间是没必要要的;一样,花费在这些服务上的系统资源也是一种浪费。
Systemd 能够提供按需启动的能力,只有在某个服务被真正请求的时候才启动它。当该服务结束,systemd 能够关闭它,等待下次须要时再次启动它。
init 系统的一个重要职责就是负责跟踪和管理服务进程的生命周期。它不只能够启动一个服务,也必须也可以中止服务。这看上去没有什么特别的,然而在真正用代码实现的时候,您或许会发现中止服务比一开始想的要困难。
服务进程通常都会做为精灵进程(daemon)在后台运行,为此服务程序有时候会派生(fork)两次。在 UpStart 中,须要在配置文件中正确地配置 expect 小节。这样 UpStart 经过对 fork 系统调用进行计数,从而获知真正的精灵进程的 PID 号。好比图 3 所示的例子:
若是 UpStart 找错了,将 p1`做为服务进程的 Pid,那么中止服务的时候,UpStart 会试图杀死 p1`进程,而真正的 p1``进程则继续执行。换句话说该服务就失去控制了。
还有更加特殊的状况。好比,一个 CGI 程序会派生两次,从而脱离了和 Apache 的父子关系。当 Apache 进程被中止后,该 CGI 程序还在继续运行。而咱们但愿服务中止后,全部由它所启动的相关进程也被中止。
为了处理这类问题,UpStart 经过 strace 来跟踪 fork、exit 等系统调用,可是这种方法很笨拙,且缺少可扩展性。systemd 则利用了 Linux 内核的特性即 CGroup 来完成跟踪的任务。当中止服务时,经过查询 CGroup,systemd 能够确保找到全部的相关进程,从而干净地中止服务。
CGroup 已经出现了好久,它主要用来实现系统资源配额管理。CGroup 提供了相似文件系统的接口,使用方便。当进程建立子进程时,子进程会继承父进程的 CGroup。所以不管服务如何启动新的子进程,全部的这些相关进程都会属于同一个 CGroup,systemd 只须要简单地遍历指定的 CGroup 便可正确地找到全部的相关进程,将它们一一中止便可。
传统的 Linux 系统中,用户能够用/etc/fstab 文件来维护固定的文件系统挂载点。这些挂载点在系统启动过程当中被自动挂载,一旦启动过程结束,这些挂载点就会确保存在。这些挂载点都是对系统运行相当重要的文件系统,好比 HOME 目录。和 sysvinit 同样,Systemd 管理这些挂载点,以便可以在系统启动时自动挂载它们。Systemd 还兼容/etc/fstab 文件,您能够继续使用该文件管理挂载点。
有时候用户还须要动态挂载点,好比打算访问 DVD 内容时,才临时执行挂载以便访问其中的内容,而不访问光盘时该挂载点被取消(umount),以便节约资源。传统地,人们依赖 autofs 服务来实现这种功能。
Systemd 内建了自动挂载服务,无需另外安装 autofs 服务,能够直接使用 systemd 提供的自动挂载管理能力来实现 autofs 的功能。
系统启动过程是由不少的独立工做共同组成的,这些工做之间可能存在依赖关系,好比挂载一个 NFS 文件系统必须依赖网络可以正常工做。Systemd 虽然可以最大限度地并发执行不少有依赖关系的工做,可是相似"挂载 NFS"和"启动网络"这样的工做仍是存在天生的前后依赖关系,没法并发执行。对于这些任务,systemd 维护一个"事务一致性"的概念,保证全部相关的服务均可以正常启动而不会出现互相依赖,以致于死锁的状况。
systemd 支持按需启动,所以系统的运行状态是动态变化的,人们没法准确地知道系统当前运行了哪些服务。Systemd 快照提供了一种将当前系统运行状态保存并恢复的能力。
好比系统当前正运行服务 A 和 B,能够用 systemd 命令行对当前系统运行情况建立快照。而后将进程 A 中止,或者作其余的任意的对系统的改变,好比启动新的进程 C。在这些改变以后,运行 systemd 的快照恢复命令,就可当即将系统恢复到快照时刻的状态,即只有服务 A,B 在运行。一个可能的应用场景是调试:好比服务器出现一些异常,为了调试用户将当前状态保存为快照,而后能够进行任意的操做,好比中止服务等等。等调试结束,恢复快照便可。
这个快照功能目前在 systemd 中并不完善,彷佛开发人员也没有特别关注它,所以有报告指出它还存在一些使用上的问题,使用时尚需慎重。
systemd 自带日志服务 journald,该日志服务的设计初衷是克服现有的 syslog 服务的缺点。好比:
syslog 不安全,消息的内容没法验证。每个本地进程均可以声称本身是 Apache PID 4711,而 syslog 也就相信并保存到磁盘上。
数据没有严格的格式,很是随意。自动化的日志分析器须要分析人类语言字符串来识别消息。一方面此类分析困难低效;此外日志格式的变化会致使分析代码须要更新甚至重写。
Systemd Journal 用二进制格式保存全部日志信息,用户使用 journalctl 命令来查看日志信息。无需本身编写复杂脆弱的字符串分析处理程序。
Systemd Journal 的优势以下:
简单性:代码少,依赖少,抽象开销最小。
零维护:日志是除错和监控系统的核心功能,所以它本身不能再产生问题。举例说,自动管理磁盘空间,避免因为日志的不断产生而将磁盘空间耗尽。
移植性:日志 文件应该在全部类型的 Linux 系统上可用,不管它使用的何种 CPU 或者字节序。
性能:添加和浏览 日志 很是快。
最小资源占用:日志 数据文件须要较小。
统一化:各类不一样的日志存储技术应该统一块儿来,将全部的可记录事件保存在同一个数据存储中。因此日志内容的全局上下文都会被保存而且可供往后查询。例如一条固件记录后一般会跟随一条内核记录,最终还会有一条用户态记录。重要的是当保存到硬盘上时这三者之间的关系不会丢失。Syslog 将不一样的信息保存到不一样的文件中,分析的时候很难肯定哪些条目是相关的。
扩展性:日志的适用范围很广,从嵌入式设备到超级计算机集群均可以知足需求。
安全性:日志 文件是能够验证的,让没法检测的修改再也不可能。
转载于:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/index.html