2018年1月

提要:对于开源软件来说,其许可证信息内嵌在源代码中。为了降低复杂性,您可以生成不同的视图。

您可以通过查看源代码找到开源软件的许可证信息。为了满足不同的需求,可以生成关于该许可证信息的不同视图或报告。

尽管直接在源代码中提供许可证信息并不是开源软件的必要条件,但是这样做的实际好处显而易见。由于开源许可证促进了软件的传播,与代码一起传输的许可证信息简化了管理过程,即使代码接收人通过间接方式获得代码,也可以使他随时可以获得权限声明。

什么是许可证条款?

在源码树中嵌入许可证信息的价值被低估了。让我们暂停一下,反思一下这种常见做法是多么有用。

什么是许可证条款呢? 对于许多开源软件来说,有一个简单的答案:一个许可证文本包含整个软件的所有许可证信息。但是开源的力量在于,它推动了其他开发者在这个起点之上进行构建,而这个过程会使许可证信息复杂化。

开源软件可以被扩展、再利用,或者与其他软件结合使用。与机械设备不同,不同群体之间的合作更具挑战性,复杂软件从许多人的工作中受益是切实可行的。开源许可证提供了促进这种开发动态的权限。具有复杂历史的软件也可能具有复杂的许可证信息。

考虑下面的例子:有人写了一个新的程序,在每个源文件中包含一个版权声明,声明该软件根据 Apache 2.0 版许可证进行许可,并且在源码树的根目录中包含 Apache 许可证文本。之后,添加了一个具有不同的版权声明的文件,以及一个 BSD 2 句版许可证副本的文件。然后,添加了一个新的子目录,其中文件具有 Apache 许可证声明,但具有标识不同版权所有者的版权声明。再之后,一个 MIT 许可证的副本添加到了新的子目录中,该子目录包含了版权声明与 MIT 许可证文件中相同的文件,但没有任何其他许可证指示信息。

这个例子表明,嵌入在源码树中的许可证信息可能很复杂而且很详细。根目录和/或各个子目录中都可能有许可证文本。一些源文件可能有许可证通知;其他源文件可能不会有。也许会有版权声明来识别各种版权所有者。但是,在不丢失信息的前提下将法律文本从代码中分离出来似乎是不可能的。因此,源代码即是许可证。

从源码树的角度来看,上面例子中对许可证信息的解释是非常简单的。但是,要在简单、明确的独立声明中获取许可证信息将是一件困难的事情。截取了源代码中所有许可证信息的许可证声明会比源代码更短,但这将是不方便的——谁会希望得到如此高度详细的单独声明?大多数用户可能会更喜欢一个概要,虽然不完整,但其获取的关键点符合自己的特定意图和敏感性要求。

用视图来概括许可证信息

对于“许可证条款是什么”这个问题,用整个源码树副本来回答可能没什么用,因为它过于庞杂和分散。大多数人只想要一个概要。但这面临一个挑战:当许可证信息比较复杂时,人们需要不同的概要,因为他们对于什么是重要的有不同的定义。

对于某些人来说,对以下问题回答“是”可能是足够的:该软件 1)是否根据一个或多个开源许可证获得许可,2)其被组装和许可后是否使得其分发和使用与所有这些许可证一致? 其他人可能需要所有许可证的列表,或者他们可能想要查看哪个软件组件对应于哪个许可证。还有一些人可能想要一个逐个组件的列表来标识任何 左版 copyleft 许可证(也许自己要做深入的左版合规研究)。 有些人可能有兴趣看到所有版权声明和软件组件的相关列表。

单一的概要可能不会满足所有人的利益。简单地将概要具体化可能会减少它对一些人的效用,而对其他人则显得不足。因此,需要将源代码中包含的许可证信息展现为不同的 “视图” views 。这里使用的“视图”术语可以视为与在数据库中使用它相似。或者,您也可以将“视图”看作是 “报告” reports

考虑将源代码作为许可证有一个优势,并且可以从中提取多个不同的视图。

您可能会尝试创建一个“全能”概要,从中可以创建其他较短的概要。但是以中间状态表达许可证信息至少有三个缺点:

  1. 时机:主概要的维护人员可能无法按计划进行更新。
  2. 版本:主概要可能基于与您使用的软件不同的版本。
  3. 质量:您的视图继承了主概要的错误和评判性。

因此,根据需要直接从您使用的源码树版本生成您的首选视图是有价值的。

有工具可以生成视图。按需视图的生成取决于工具。许可证信息展示的清晰(或混乱)程度会促进(或妨碍)该工具的功效。我们不需要许可证信息的特定机器编码,但是我们应该充分利用众多经验来源,以既可以被人读取,也可以被机器提取的方式来表达信息。

Jeff Kaufman 在他的文章《开源软件许可证合规的经济高效模型》中指出:由于源代码包含许可证信息,因此分发源代码是满足某些许可证要求的有效方式。

将所有许可证信息嵌入到源码树中是最佳实践。如果您发现源码树中没有显示许可证信息,请考虑通过提交错误报告来改进该项目,建议将该信息添加到源码树中。

源代码即是许可证。从完整的记录中,可以生成许可证信息的视图。工具可以将许可证信息提取到各种报告中,以满足特定需求或敏感性要求。

为了获得这个愿景的全部好处,我们还有工作要做。您对工具状态以及许可证信息展现有什么看法呢?


作者简介:Scott Peterson 是红帽公司法律团队成员。很久以前,一位工程师就一个叫做 GPL 的奇怪文件向 Scott 征询法律建议,这个致命的问题让 Scott 走上了探索包括技术标准和开源软件在内的协同开发法律问题的纠结之路。

译者简介:薛亮,集慧智佳知识产权咨询公司高级咨询师,擅长专利检索、专利分析、竞争对手跟踪、FTO分析、开源软件知识产权风险分析,致力于为互联网企业、高科技公司提供知识产权咨询服务。

学习怎么在保护 root 密码的安全性的同时,为可信用户赋予所管理的网络功能和特定服务的权限。

我最近写了一个简短的 Bash 程序来将 MP3 文件从一台网络主机的 USB 盘中拷贝到另一台网络主机上去。拷贝出来的文件存放在一台志愿者组织所属服务器的特定目录下,在那里,这些文件可以被下载和播放。

我的程序还会做些其他事情,比如为了自动在网页上根据日期排序,在拷贝文件之前会先对这些文件重命名。在验证拷贝完成后,还会删掉 USB 盘中的所有文件。这个小程序还有一些其他选项,比如 -h 会显示帮助, -t 进入测试模式等等。

我的程序需要以 root 运行才能发挥作用。然而,这个组织中之后很少的人对管理音频和计算机系统有兴趣的,这使得我不得不找那些半吊子的人来,并培训他们登录到用于传输的计算机,运行这个小程序。

倒不是说我不能亲自运行这个程序,但由于外出和疾病等等各种原因, 我不是时常在场的。 即使我在场,作为一名 “懒惰的系统管理员”, 我也希望别人能替我把事情给做了。 因此我写了一些脚本来自动完成这些任务并通过 sudo 来指定某些人来运行这些脚本。 很多 Linux 命令都需要用户以 root 身份来运行。 sudo 能够保护系统免遭一时糊涂造成的意外损坏以及恶意用户的故意破坏。

尽可能的使用 sudo

sudo 是一个很方便的工具,它让我一个具有 root 权限的管理员可以分配所有或者部分管理性的任务给其他用户, 而且还无需告诉他们 root 密码, 从而保证主机的高安全性。

假设,我给了普通用户 ruser 访问我 Bash 程序 myprog 的权限, 而这个程序的部分功能需要 root 权限。 那么该用户可以以 ruser 的身份登录,然后通过以下命令运行 myprog

sudo myprog

sudo 程序会检查 /etc/sudoers 文件,并确认 ruser 是否被许可运行 myprog。如被许可,sudo 会要求该用户输入其密码——而非 root 密码。在 ruser 输入他的密码之后,该程序就运行了。此外,sudo 也记录 myprog 该程序运行的日期和时间、完整的命令,以及谁在运行它。这个数据会记录在 /var/log/security 中。

我发现在培训时记录下每个用 sudo 执行的命令会很有帮助。我可以看到谁执行了哪些命令,他们是否输对了。

我委派了权限给自己和另一个人来运行那一个程序;然而,sudo 可以做更多的事情。 它允许系统管理员委派所管理的网络功能或特定的服务给某个受信的人或某组人。这可以让你在保护了 root 密码的安全性的同时,也赋予了那些功能。

配置 sudoers 文件

作为一名系统管理员,我使用 /etc/sudoers 文件来设置某些用户或某些用户组可以访问某个命令,或某组命令,或所有命令。 这种灵活性是使用 sudo 进行委派时能兼顾功能与简易性的关键。

我一开始对 sudoers 文件感到很困惑,因此下面我会拷贝并分解我所使用主机上的完整 sudoers 文件。 希望在分析的过程中不会让你感到困惑。 我意外地发现, 基于 Red Hat 的发行版中默认的配置文件都会很多注释以及例子来指导你如何做出修改,这使得修改配置文件变得简单了很多,也不需要在互联网上搜索那么多东西了。

不要直接用编辑器来修改 sudoers 文件,而应该用 visudo 命令,因为该命令会在你保存并退出编辑器后就立即生效这些变更。 visudo 也可以使用除了 Vi 之外的其他编辑器。

让我们首先来分析一下文件中的各种别名。

主机别名

主机别名这一节用于创建主机分组,授予该组主机可以访问哪些命令或命令别名。 它的基本思想是,该文件由组织中的所有主机共同维护,然后拷贝到每台主机中的 /etc 中。 其中有些主机, 例如各种服务器, 可以配置成一个组来赋予用户访问特定命令的权限, 比如可以启停类似 HTTPD、DNS 以及网络服务;可以挂载文件系统等等。

在设置主机别名时也可以用 IP 地址替代主机名。

## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using 
## wildcards for entire domains) or IP addresses instead.
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

用户别名

用户别名允许 root 将用户整理成别名组中,并按组来分配特定的 root 权限。在这部分内容中我加了一行 User_Alias AUDIO = dboth, ruser,定义了一个别名 AUDIO 用来指代了两个用户。

正如 sudoers 文件中所阐明的,也可以直接使用 /etc/groups 中定义的组而不用自己设置别名。 如果你定义好的组(假设组名为 audio)已经能满足要求了, 那么在后面分配命令时只需要在组名前加上 % 号,像这样: %audio

## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname 
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
User_Alias AUDIO = dboth, ruser

命令别名

再后面是命令别名的部分。这些别名表示的是一系列相关的命令, 比如网络相关命令,或者 RPM 包管理命令。 这些别名允许系统管理员方便地为一组命令分配权限。

该部分内容已经设置好了许多别名,这使得分配权限给某类命令变得方便很多。

## Command Aliases
## These are groups of related commands...

## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp 

## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe

环境默认值

下面部分内容设置默认的环境变量。这部分最值得关注的是 !visiblepw 这一行, 它表示当用户环境设置成显示密码时禁止 sudo 的运行。 这个安全措施不应该被修改掉。


# Defaults specification

#
# Refuse to run if unable to disable echo on the tty.
#
Defaults   !visiblepw

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"


Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

命令部分

命令部分是 sudoers 文件的主体。不使用别名并不会影响你完成要实现的效果,别名只是让整个配置工作大幅简化而已。

这部分使用之前定义的别名来告诉 sudo 哪些人可以在哪些机器上执行哪些操作。一旦你理解了这部分内容的语法,你会发现这些例子都非常的直观。 下面我们来看看它的语法。

ruser           ALL=(ALL) ALL 

意即 ruser 可以在任意主机上以任意用户身份运行任意命令

这是一条为用户 ruser 做出的配置。行中第一个 ALL 表示该条规则在所有主机上生效。 第二个 ALL 允许 ruser 以任意其他用户的身份运行命令。 默认情况下, 命令以 root 用户的身份运行, 但 ruser 可以在 sudo 命令行指定程序以其他用户的身份运行。 最后这个 ALL 表示 ruser 可以运行所有命令而不受限制。 这让 ruser 实际上就变成了 root

注意到下面还有一条针对 root 的配置。这允许 root 能通过 sudo 在任何主机上运行任何命令。

root    ALL=(ALL) ALL 

意即 root 可以在任意主机上以任意用户身份运行任意命令

为了实验一下效果,我注释掉了这行, 然后以 root 的身份试着直接运行 chown。 出乎意料的是这样是能成功的。 然后我试了下 sudo chown,结果失败了,提示信息 “Root is not in the sudoers file。 This incident will be reported”。 也就是说 root 可以直接运行任何命令, 但当加上 sudo 时则不行。 这会阻止 root 像其他用户一样使用 sudo 命令来运行其他命令, 但是 root 有太多种方法可以绕过这个约束了。

下面这行是我新增来控制访问 myprog 的。它指定了只有上面定义的 AUDIO 组中的用户才能在 guest1 这台主机上使用 myprog 这个命令。

AUDIO   guest1=/usr/local/bin/myprog

允许 AUDIO 组成员在 guest1 主机上访问 myprog

注意,上面这一行只指定了允许访问的主机名和程序,而没有说用户可以以其他用户的身份来运行该程序。

省略密码

你也可以通过 NOPASSWORD 来让 AUDIO 组中的用户无需密码就能运行 myprog。像这样:

AUDIO   guest1=NOPASSWORD : /usr/local/bin/myprog

允许 AUDIO 组成员在 guest1 主机上不用输入密码即可访问 myprog

我并没有这样做,因为我觉得使用 sudo 的用户必须要停下来想清楚他们正在做的事情,这对他们有好处。 我这里只是举个例子。

wheel

sudoers 文件中命令部分的 wheel 说明(如下所示)允许所有在 wheel 组中的用户在任何机器上运行任何命令。wheel 组在 /etc/group 文件中定义, 用户必须加入该组后才能工作。 组名前面的 % 符号表示 sudo 应该去 /etc/group 文件中查找该组。

%wheel          ALL = (ALL) ALL

运行所有定义在 /etc/group 文件中的 “wheel” 组成员可以在任意主机上运行全部命令

这种方法很好的实现了为多个用户赋予完全的 root 权限而不用提供 root 密码。只需要把该用户加入 wheel 组中就能给他们提供完整的 root 的能力。 它也提供了一种通过 sudo 创建的日志来监控他们行为的途径。 有些 Linux 发行版, 比如 Ubuntu, 会自动将用户的 ID 加入 /etc/group 中的 wheel 组中, 这使得他们能够用 sudo 命令运行所有的特权命令。

结语

我这里只是小试了一把 sudo — 我只是给一到两个用户以 root 权限运行单个命令的权限。完成这些只添加了两行配置(不考虑注释)。 将某项任务的权限委派给其他非 root 用户非常简单,而且可以节省你大量的时间。 同时它还会产生日志来帮你发现问题。

sudoers 文件还有许多其他的配置和能力。查看 sudosudoers 的 man 手册可以深入了解详细信息。


via: https://opensource.com/article/17/12/using-sudo-delegate

作者:David Both 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

明明有很多剩余空间,但 Linux 系统依然提示没有空间剩余。为什么会这样呢?Linux 偶尔会有一些令人沮丧的模糊的错误消息出现,而这就是其中一种。不过这种错误通常都是由某几种因素导致的。

通过 du 和 df 检查磁盘空间

在开始行动前,最好先检查一下是否磁盘上是否确实还有空间剩余。虽然桌面环境的工具也很不错,但命令行上的工具更直接,要好的多。

 title=

首先让我们看看 du 命令。用它来检查问题磁盘所在的挂载点目录。本文假设出问题的分区挂载点为根目录。

sudo du -sh /

 title=

由于它要遍历磁盘中的所有文件,因此需要花费一点时间。现在再让我们试试 df

sudo df -h

把根目录和在其中挂载的文件系统加在这条命令的后面。比如,若你的有一个独立的磁盘挂载到 /home,那么除了根目录之外,你也需要把它加进来。使用空间的总和应该跟你 du 命令得到的结果接近。否则的话,就说明可能有已删除文件的文件被进程占用。

当然,这里主要专注点在于这些命令的结果是否要小于磁盘的大小。如果确实小于磁盘大小,那么很明显有很多地方不对劲。

相关使用 Agedu 分析硬盘空间使用状况

可能的原因

这里列出了一些产生这种情况的主要原因。若你发现 dudf 的结果之间有差别,那么可以直接检查第一项原因。否则从第二项原因开始检查。

已删除文件被进程所占用

有时,文件可能已经被删掉了,但有进程依然在使用它。在进程运行期间,Linux 不会释放该文件的存储空间。你需要找出这个进程然后重启这个进程。

 title=

使用下面命令来定位进程。

sudo lsof / | grep deleted

这应该会列出出问题的进程了,然后重启该进程。

sudo systemctl restart service_name

i 节点不够了

 title=

文件系统中有一些称为 “ i 节点 inode ” 的元数据,其用来保存文件的相关信息。很多文件系统中的 i 节点数量是固定的,因此很可能 i 节点已经耗尽了而文件系统本身还没有用完。你可以使用 df 来检查。

sudo df -i /

比较一下已用的 i 节点和总共的 i 节点数量。如果没有可用的 i 节点了,那么很不幸,你也无法扩充 i 节点。删除一些无用的和过期的文件来释放一些 i 节点吧。

坏块

最后一个很常见的问题就是坏的文件系统块。除非另有标记,否则操作系统很可能会认为这些块都是可用的,这会导致文件系统损坏或者硬盘坏死。最好是使用带 -cc 标志的 fsck 搜索并标记出这些块。记住,你不能使用正在使用的文件系统(LCTT 译注:即包含坏块的文件系统)中的 fsck 命令。你应该会要用到 live CD。

sudo fsck -vcck /dev/sda2

很明显,这里需要使用你想检查的磁盘路径取代命令中的磁盘位置。另外,要注意,这恐怕会花上很长一段时间。

相关:[使用 fsck 检查并修复你的文件系统 [Linux]](https://www.maketecheasier.com/check-repair-filesystem-fsck-linux/ "Check and Repair Your Filesystem With fsck [Linux]")

希望这些方案能解决你的问题。这种问题在任何情况下都不是那么容易诊断的。但是,在运气好的情况下,你可以把文件系统清理干净并让你的硬盘再次正常工作。


via: https://www.maketecheasier.com/fix-linux-no-space-left-on-device-error/

作者:Nick Congleton 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我们希望更好地将 Reddit 的规模传达给我们的用户。到目前为止,投票得分和评论数量是特定的帖子活动的主要指标。然而,Reddit 有许多访问者在没有投票或评论的情况下阅读内容。我们希望建立一个能够捕捉到帖子阅读数量的系统。然后将该数量展示给内容创建者和版主,以便他们更好地了解特定帖子上的活动。

在这篇文章中,我们将讨论我们如何大规模地实现计数。

计数方法

对浏览计数有四个主要要求:

  • 计数必须是实时的或接近实时的。不是每天或每小时的总量。
  • 每个用户在短时间内只能计数一次。
  • 显示的数量与实际的误差在百分之几。
  • 系统必须能够在生产环境运行,并在事件发生后几秒内处理事件。

满足这四项要求比听起来要复杂得多。为了实时保持准确的计数,我们需要知道某个特定的用户是否曾经访问过这个帖子。要知道这些信息,我们需要存储先前访问过每个帖子的用户组,然后在每次处理对该帖子的新访问时查看该组。这个解决方案的一个原始实现是将这个唯一用户的集合作为散列表存储在内存中,并且以帖子 ID 作为键名。

这种方法适用于浏览量较少的文章,但一旦文章流行,阅读人数迅速增加,这种方法很难扩展。有几个热门的帖子有超过一百万的唯一读者!对于这种帖子,对于内存和 CPU 来说影响都很大,因为要存储所有的 ID,并频繁地查找集合,看看是否有人已经访问过。

由于我们不能提供精确的计数,我们研究了几个不同的基数估计算法。我们考虑了两个非常符合我们期望的选择:

  1. 线性概率计数方法,非常准确,但要计数的集合越大,则线性地需要更多的内存。
  2. 基于 HyperLogLog(HLL)的计数方法。HLL 随集合大小 次线性 sub-linearly 增长,但不能提供与线性计数器相同的准确度。

要了解 HLL 真正节省的空间大小,看一下这篇文章顶部包括的 r/pics 帖子。它有超过 100 万的唯一用户。如果我们存储 100 万个唯一用户 ID,并且每个用户 ID 是 8 个字节长,那么我们需要 8 兆内存来计算单个帖子的唯一用户数!相比之下,使用 HLL 进行计数会占用更少的内存。每个实现的内存量是不一样的,但是对于这个实现,我们可以使用仅仅 12 千字节的空间计算超过一百万个 ID,这将是原始空间使用量的 0.15%!

这篇关于高可伸缩性的文章很好地概述了上述两种算法。)

许多 HLL 实现使用了上述两种方法的组合,即对于小集合以线性计数开始,并且一旦大小达到特定点就切换到 HLL。前者通常被称为 “稀疏” HLL 表达,而后者被称为“密集” HLL 表达。混合的方法是非常有利的,因为它可以提供准确的结果,同时保留适度的内存占用量。这个方法在 Google 的 HyperLogLog++ 论文中有更详细的描述。

虽然 HLL 算法是相当标准的,但在我们的实现中我们考虑使用三种变体。请注意,对于内存中的 HLL 实现,我们只关注 Java 和 Scala 实现,因为我们主要在数据工程团队中使用 Java 和 Scala。

  1. Twitter 的 Algebird 库,用 Scala 实现。Algebird 有很好的使用文档,但是稀疏和密集的 HLL 表达的实现细节不容易理解。
  2. 在 stream-lib 中的 HyperLogLog++ 的实现,用 Java 实现。stream-lib 中的代码有很好的文档,但是要理解如何正确使用这个库并且调整它以满足我们的需求是有些困难的。
  3. Redis 的 HLL 实现(我们选择的)。我们认为,Redis 的 HLL 实施方案有很好的文档并且易于配置,所提供的 HLL 相关的 API 易于集成。作为一个额外的好处,使用 Redis 通过将计数应用程序(HLL 计算)的 CPU 和内存密集型部分移出并将其移至专用服务器上,从而缓解了我们的许多性能问题。

Reddit 的数据管道主要围绕 Apache Kafka。当用户查看帖子时,事件被激发并发送到事件收集器服务器,该服务器批量处理事件并将其保存到 Kafka 中。

从这里,浏览计数系统有两个按顺序运行的组件。我们的计数架构的第一部分是一个名为 Nazar) 的 Kafka 消费者,它将读取来自 Kafka 的每个事件,并通过我们编制的一组规则来确定是否应该计算一个事件。我们给它起了这个名字是因为 Nazar 是一个保护你免受邪恶的眼形护身符,Nazar 系统是一个“眼睛”,它可以保护我们免受不良因素的影响。Nazar 使用 Redis 保持状态,并跟踪不应计算浏览的潜在原因。我们可能无法统计事件的一个原因是,由于同一用户在短时间内重复浏览的结果。Nazar 接着将改变事件,添加一个布尔标志表明是否应该被计数,然后再发回 Kafka 事件。

这是这个项目要说的第二部分。我们有第二个叫做 Abacus 的 Kafka 消费者,它实际上对浏览进行计数,并使计数在网站和客户端可见。Abacus 读取 Nazar 输出的 Kafka 事件。接着,根据 Nazar 的决定,它将计算或跳过本次浏览。如果事件被标记为计数,那么 Abacus 首先检查 Redis 中是否存在已经存在与事件对应的帖子的 HLL 计数器。如果计数器已经在 Redis 中,那么 Abacus 向 Redis 发出一个 PFADD 的请求。如果计数器还没有在 Redis 中,那么 Abacus 向 Cassandra 集群发出请求,我们用这个集群来持久化 HLL 计数器和原始计数,并向 Redis 发出一个 SET 请求来添加过滤器。这种情况通常发生在人们查看已经被 Redis 删除的旧帖的时候。

为了保持对可能从 Redis 删除的旧帖子的维护,Abacus 定期将 Redis 的完整 HLL 过滤器以及每个帖子的计数记录到 Cassandra 集群中。 Cassandra 的写入以 10 秒一组分批写入,以避免超载。下面是一个高层的事件流程图。

总结

我们希望浏览量计数器能够更好地帮助内容创作者了解每篇文章的情况,并帮助版主快速确定哪些帖子在其社区拥有大量流量。未来,我们计划利用数据管道的实时潜力向更多的人提供更多有用的反馈。

如果你有兴趣解决这样的问题,请查看我们的职位页面


via: https://redditblog.com/2017/05/24/view-counting-at-reddit/

作者:Krishnan Chandra 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

FSCK 是一个很重要的 Linux/Unix 工具,它用于检测并修复文件系统中的错误。它类似于 Windows 操作系统中的 “chkdsk” 工具,但它是为 Linux、MacOS、FreeBSD 操作系统所准备的。

FSCK 全称为 File System Consistency Check。在大多数时候,它在系统启动时运行,但是如果需要的话,它也能被超级用户手工启动。

它可以进行三种模式的操作,

  1. 查错并在发现错误时由用户决定如何处理,
  2. 查错并自动修复,
  3. 查错但在发现错误时只显示错误而不进行修复。

FSCK 的语法

手工执行 FSCK 的语法为,

$ fsck options drives

fsck 支持的选项有,

  • -p 自动修复(不询问)
  • -n 不对文件系统做出改动
  • -y 对所有问题都回答 "yes"
  • -c 检查所有的坏块并将之添加到坏块列表中
  • -f 即使文件系统标记为 clean 也强制进行检查
  • -v 输出详细信息
  • -b superblock 使用替代的超级块
  • -B blocksize 指定超级块的块大小
  • -j external_journal 指定外部日志的位置
  • -l bad_blocks_file 添加到指定的坏块列表(文件)
  • -L bad_blocks_file 指定坏块列表(文件)

我们可以根据要做的操作任意指定这些选项。下面让我们来看一些例子。

Fsck 命令的案例

注意: 在开始讨论案例之前,请先读完这段话。我们不应该用 fsck 检查已挂载的磁盘,这很可能会对磁盘造成永久性的伤害。因此在开始使用 fsck 之前,我们需要使用下面命令来卸载磁盘,

$ umount drivename

比如像这样,

$ umount /dev/sdb1

可以通过下面命令来查看分区编号,

$ fdisk -l

另外,在运行 fsck 时,可能出错并返回一些错误码。下面是一些常见的错误及其意义的列表,

  • 0 - 没有错误
  • 1 - 修复了一些文件系统错误
  • 2 - 系统需要被重启
  • 4 - 文件系统错误未被修复
  • 8 - 操作错
  • 16 - 使用或语法错
  • 32 - fsck 被用户取消
  • 128 - 共享库出错

现在让我们来看一些 fsck 命令的例子,

在单个分区上进行错误检查

在终端运行下面过命令来对单个分区进行检查,

$ umount /dev/sdb1
$ fsck /dev/sdb1

检查文件系统错误并自动修复

使用选项 -a 进行一致性检查并自动修复这些错误。也可以用 -y 替代 -a 选项。

$ fsck -a /dev/sdb1

检查文件系统错误但并不进行修复

若我们只想知道文件系统上有哪些错误而不想修复这些错误,那么可以使用选项 -n

$ fsck -n /dev/sdb1

检查所有分区中的错误

-A 选项一次性检查所有分区上的文件系统错误,

$ fsck -A

若要禁止对根文件系统进行检查可以使用选项 -R

$ fsck -AR

只检查指定文件系统类型的分区

使用选项 -t 及文件系统类型,可以让 fsck 只检查指定文件系统类型的分区,比如指定文件系统类型为 “ext4”,

$ fsck -t ext4 /dev/sdb1

或者,

$ fsck -t -A ext4

只在卸载的磁盘上进行一致性检查

要保证 fsck 只在卸载的磁盘上操作,可以使用选项 -M

$ fsck -AM

这就是我们的案例教程了。有任何疑问欢迎在下面的留言框中留言。


via: http://linuxtechlab.com/linux-filesystem-errors-fsck-command-with-examples/

作者:Shusain 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我们中的许多人经常查看 man 页面 来了解命令开关(选项),它会显示有关命令语法、说明、细节和可用的选项,但它没有任何实际的例子。因此,在组合成一个我们需要的完整命令时会遇到一些麻烦。

你确实遇到这个麻烦而想要一个更好的解决方案吗?我会建议你试一下 cheat

Cheat 是什么

cheat 允许你在命令行中创建和查看交互式的 速查表 cheatsheet 。它旨在帮助提醒 *nix 系统管理员他们经常使用但还没频繁到会记住的命令的选项。

如何安装 Cheat

cheat 是使用 python 开发的,所以可以用 pip 来在你的系统上安装 cheat

pip 是一个与 setuptools 捆绑在一起的 Python 模块,它是在 Linux 中安装 Python 包推荐的工具之一。

对于 Debian/Ubuntu 用户,请使用 apt-get 命令apt 命令来安装 pip

[对于 Python2]
$ sudo apt install python-pip python-setuptools
[对于 Python3]
$ sudo apt install python3-pip

RHEL/CentOS 官方仓库中没有 pip,因此使用 EPEL 仓库,并使用 YUM 命令安装 pip

$ sudo yum install python-pip python-devel python-setuptools

对于 Fedora 系统,使用 dnf 命令来安装 pip

[对于 Python2]
$ sudo dnf install python-pip
[对于 Python3]
$ sudo dnf install python3

对于基于 Arch Linux 的系统,请使用 Pacman 命令 来安装 pip

[对于 Python2]
$ sudo pacman -S python2-pip python-setuptools
[对于 Python3]
$ sudo pacman -S python-pip python3-setuptools

对于 openSUSE 系统,使用 Zypper 命令来安装 pip

[对于 Python2]
$ sudo pacman -S python-pip
[对于 Python3]
$ sudo pacman -S python3-pip

pip 来在你的系统上安装 cheat

$ sudo pip install cheat

如何使用 Cheat

运行 cheat,然后按相应的命令来查看速查表,作为例子,我们要来看下 tar 命令的例子。

$ cheat tar
# To extract an uncompressed archive:
tar -xvf /path/to/foo.tar

# To create an uncompressed archive:
tar -cvf /path/to/foo.tar /path/to/foo/

# To extract a .gz archive:
tar -xzvf /path/to/foo.tgz

# To create a .gz archive:
tar -czvf /path/to/foo.tgz /path/to/foo/

# To list the content of an .gz archive:
tar -ztvf /path/to/foo.tgz

# To extract a .bz2 archive:
tar -xjvf /path/to/foo.tgz

# To create a .bz2 archive:
tar -cjvf /path/to/foo.tgz /path/to/foo/

# To extract a .tar in specified Directory:
tar -xvf /path/to/foo.tar -C /path/to/destination/

# To list the content of an .bz2 archive:
tar -jtvf /path/to/foo.tgz

# To create a .gz archive and exclude all jpg,gif,... from the tgz
tar czvf /path/to/foo.tgz --exclude=\*.{jpg,gif,png,wmv,flv,tar.gz,zip} /path/to/foo/

# To use parallel (multi-threaded) implementation of compression algorithms:
tar -z ... -> tar -Ipigz ...
tar -j ... -> tar -Ipbzip2 ...
tar -J ... -> tar -Ipixz ...

运行下面的命令查看可用的速查表。

$ cheat -l

进入帮助页面获取更多详细信息。

$ cheat -h

via: https://www.2daygeek.com/cheat-a-collection-of-practical-linux-command-examples/

作者:Magesh Maruthamuthu 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出