pydoc 模块和 `help()` 函数的关系

查看原文

Python pydoc 模块是 Python 的内建模块,用于在运行时提供 help text。它能将 docstring 抽出来,变成文档。

  • 你可以用命令行工具 pydoc 查看某个模块的文档,例如 pydoc str, pydoc atexit
  • 你可以加上 -w 参数生成 HTML 文档:pydoc -w atexit,它将生成 atexit.html 文档。
  • 当然,你也可以通过 help('atexit') 查看其文档。
read more

Unix `/proc/$/status` 的数据格式是如何设计的?

查看原文

如果运行 cat /proc/$$/status | grep Sig,你会看到当前进程的关于如何处理信号的配置。

  • SigQ: 进程 real user id 的信号队列中的信号数量
  • SigPnd: Pending 的信号数量
  • SigBlk: 堵塞的信号
  • SigLg: 忽略的信号
  • SigCgt: 捕获的信号

如果见到 SigCgt: 000000004b817efb,并不是说捕获了 4b817efb 个信号,而是说当前进程想要捕获哪些信号。这个数字可以转化为 01001011 10000001 01111110 11111011,其中每个比特位代表一种信号类型,例如最后的 1 是 SIGHUP, 倒数第二个 1 是 SIGINT。

如果想要忽略 ctrl-c, 就可以用 signal(SIGINT, SIG_IGN …

read more

Real User ID v/s Effect User ID v/s ...

查看原文

Unix 操作系统鉴别用户的方式是通过内核提供的 user identifier (user ID, uid) 这个值。UID 会和一个 group identifier (GID) 相关联,用于决定系统资源的访问权限。命令行工具 id 可以查看当前用户的 UID 以及用户名,组。关于跑着的进程,会涉及到好几个 UID 的概念:

  • euid, Effective user ID:系统用于检查权限。进程新建文件时,文件的 owner 也会用进程的 euid。
  • fsuid, File system user ID: 历史上曾经出现过的一个概念,简单可以理解为就是 euid。
  • suid, Saved user ID: 进程跑着的时候,需要降权做一些操作 …
read more

穿越虫洞 - 学习 Facebook Pub/Sub 系统设计

查看原文

Wormhole 是 Facebook 发布的 pub/sub 系统,它的设计目标是实时地,可靠地,将一个数据库的数据发送到多个订阅者服务那里去。订阅者服务可以是缓存(要更新数据),服务(要重建索引或更新数据),数据仓库(灌数据进 Hadoop, Hive)。

这个系统有三个核心组件:

  • Producer: 一个 library,内建在应用方的程序里面。
  • Publisher: 持续读 bin log 数据,转为实时流发送到别的系统去。
  • Consumer

这个系统有一些有用的特性,例如:

  • Shard 的数据库可以并行地运行虫洞 publisher
  • 支持从检查点重新开始产生流,做故障恢复
  • 可靠的有序的递送,消息至少会被发送一次,最近更新的数据会被更晚送达。
  • 只要是 bin log 中出现的数据,publisher 就会递送它。
  • 基于 stream,延迟很低 …
read more

图数据库起步:ACID v/s BASE

查看原文

数据库有两种一致性模型,ACID 和 BASE。

  • ACID:Atomic, Consistent,Isolated, Durable。这四个特性保证一个事务是完整的,其数据是一致的,持久地存储在硬盘上。
  • BASE:Basic Availability,Soft-state,Eventual Consistency。BASE 比 ACID 更宽松,它优先考虑可用性,不保证写时 replicated 数据的一致性,但能保证最终一致性。

这两种数据库一致性模型适应的场景不太一样,如果用 BASE,那得在应用层面对数据一致性有一些处理。

read more

如何防止软件失效将变为灾难!

查看原文

千年虫问题是进入 21 世纪时软件行业的大问题,大家都如临大敌,为此整整准备了一年甚至更久,写了各种脚本,更新了所有软件。有的 SA 甚至可以放心的离开岗位去休假。千年虫问题可能没那么严重,但行业对其的反应折射出了我们对风险对抗的认知:及时修复,降低风险,使软件失效不至于编程大灾难。

我们对于灾难的预处理,基本上都围绕着降低风险来做。如果有地方会引起问题,我们就会加倍注意。越大的可能性会引起我们越多的注意力。我们可能无法想到所有的可能性,但至少能处理已知的问题。

设立独立的安全区是一个常见的手段,在这个安全区里面我们想办法让这个子系统能够容忍风险,然后在想办法尽可能地将它与外部系统做好隔离。事实上,PR 和 code review 就是一种降低风险的手段,让别人和你一起把风。

另外一种手段是让系统尽可能的可预知,我们预测系统所有可能的状态,遍历所有的状态,要么想出怎么人工处理,要么修复它。

小步快跑也是个降低风险的手段,每次做一点改变。

read more

如何应对让你觉得痛苦的任务:分解+反馈+自动化

查看原文

在体育运动中,如果不经常锻炼,就会容易受伤。软件开发在这一点是类似的,如果经常做一件事情,它的难度就会降低。比如说,持续集成就是这种将频率死命抬上去,最后部署的流程反而变的简单了(一天能部署想几次就几次)。当然,持续做也是要有技巧的,你要好好分解任务,快速得到反馈调整做事情的方法,最后尽可能自动化。

衍生思考:觉得很麻烦的事情,让自己经常做,逼自己去找各种省力的办法,让事情的解决方案变得更高效。

read more

如何设计像 Kafka 这样的分布式日志系统的存储方案?

查看原文

日志是一种线性序的,只增加数据的数据结构,通常来说内容就是时间戳和内容数据,被添加到文件的末尾。虽然说起来这么简单,但要做到满足企业海量的日志数据的生成,就得引入像 Kafka 这样的系统。企业需求:高性能,高可用,可扩展,为了满足这些,我们也就要去实现领导选举,数据 replication,日志持久化,消息队列等等。

跟消息队列不同的是,消息只会被添加不会被删除,另外有基于某些规则的保留 (retention)能力。我们还有一些需求是定点重放,从某个日志记录开始读取数据,这意味着我们要做二分查找。

理论上来说,日志是无限增长的,单纯的文件不足以应对无限的数据。为了解决数据存储, Kafka 引入了 Chunk,不直接存储数据进文件,而是存进一个个小区块里,再把区块的索引登记到 index file 里。

为了性能考虑,我们尽可能要用到操作系统的页缓存,避免磁盘读操作。为此我们数据存储的时候可以直接将数据格式设定存储网络序,这样从内存页中可以直接转到 socket buffer 上(zero …

read more

把用户丢来的 BUG 标记为不解决(Won't Fix)

查看原文

做工程的首要考虑,既不是安全,也不是性能,而是能工作,能用。我们设计系统愿望总是好的,希望它每一个状态我们都能考虑到,但事实是,总有可能有意料之外的输入或影响,因此设计一个能容错的,能接纳不一致状态的系统是有意义的。本文提到了作者在处理请求 hostname 和 证书签的不一样,但作者决定还是承认这是可以用的输入,因为在一些特定的场景,仍然想让其工作,所以作者将那个 Case 标为 不解决。

衍生思考:作者做了一个 Tradeoff,在安全和快猛糙中间选择了快猛糙。事实上,作者遇到的场景并不只有这个解法,但他想说的问题相信很多人都在经历:任务无穷无尽,我们要做出一个对于当下合理的选择,这可能会有一些代价,但也是值得的。

read more

Web 应用程序的缓存方案如何选择?

查看原文

当 Web 应用程序遇到流量增长,上缓存就是必须的手段,因为缓存让我们不再读取磁盘,减少 IO,是个能快速提升系统性能的手段。论方法,Web 程序使用的缓存有两种:进程内和进程外。

  • 进程内的缓存:使用诸如 Python @lru_cache 之类的方法在进程里面缓存住返回值。好处是没有方法能比它更快了更简单了,你甚至不需要做序列化,任何编程语言的对象或者结构数据都能放进缓存。缺点是没法在进程间共用,程序重启需要重新构建缓存。
  • 进程间的缓存:使用诸如 Memcached,Redis 等工具。利弊和上面相反,速度降了,需要做数据序列化,但能多进程多主机共用,程序重启不影响缓存。

引入缓存后,一个特别需要注意的问题就是何时让缓存过期,毕竟方法过段时间可能会返回不同的值。最简单的方法是设置过期时间,例如 1h, 1d 等。另外的做法是做更新或删除操作的时候主动清缓存,不过实现就麻烦了,尽管大多人会选择这个方案。

read more

« Page 39 / 54 »