#895 转载:进程模型、线程模型,PostgreSQL 正面临抉择

2023-06-20

面向进程模型是一种数据库系统的架构模型,核心思想是将不同的数据库服务分配给不同的进程,每个进程独立运行,相互之间通过进程间通信(IPC)进行协作。
这种模型被广泛应用于数据库系统中,例如 PostgreSQL 数据库系统。

正如上文所说,进程模型使得 PostgreSQL 可以将不同的服务分配给多个进程独立运行,每个进程负责不同的任务,例如查询处理、并发控制、锁管理等。
进程模型还可以可以保证系统的稳定性和可靠性。当一个进程出现问题时,不会影响到其他进程的正常运行,从而提高了系统的可用性。

这样的特点使得 PostgreSQL 可以同时处理大量的并发请求,提高了系统的性能和响应速度;
除此之外,PostgreSQL 还可以很容易地进行水平扩展,增加更多的节点以应对更高的负载。
不过与此同时,也让 PostgreSQL 面对着管理和维护成本相对较高、需要较为复杂的进程间通信和协调机制、需要消耗更多的系统资源等缺点。

6 月初,Heikki Linnakangas 发布了将 PostgreSQL 转为线程模型的提案。

线程模型是一种数据库系统的架构模型,与面向进程模型类似,它是将不同的数据库服务分配给不同的线程,每个线程独立运行,相互之间通过线程间通信进行协作。线程模型在一些轻量级的数据库系统中得到广泛应用,例如 SQLite。

线程模型与进程模型的最大区别在于,线程模型中所有的线程共享同一个进程的地址空间,每个线程有自己的堆栈,共享代码段和数据段。这意味着线程之间可以直接访问同一份内存,因此线程间通信的成本相对较低,不过这也意味着线程间的数据共享可能会带来安全性问题。

从进程模型转换成线程模型的优缺点:

优点

  1. 更轻量级:线程模型相对于进程模型更加轻量级,可以更加高效地使用系统资源,尤其是在单机上运行多个实例时,线程模型可以将多个实例运行在同一个进程中,减少了系统调用和进程间通信带来的开销。
  2. 更高的响应速度:线程模型中线程之间的通信成本相对较低,因此在高并发场景下具有更高的响应速度。
  3. 更少的内存占用:线程模型中线程共享同一份地址空间,因此可以避免进程模型中同一份代码和数据被多个进程重复加载到内存的问题,节省了系统内存占用。

缺点

  1. 安全性问题:线程之间共享同一份内存,可能会带来安全性问题,例如数据竞争和锁竞争等。
  2. 可靠性问题:线程模型中一个线程崩溃可能会影响到整个进程的稳定性和可靠性。
  3. 多线程编程难度较大:线程之间的通信需要进行同步和互斥,编写多线程程序的难度相对较大。

PostgreSQL 开发者、EnterpriseDB 高级数据库架构师 Andres Freund 指出:

我认为原有流程模型开始产生诸多限制,这个问题在大型设备上体现得尤其明显。
跨进程上下文切换所带来的开销,原本就比在同一进程内的不同线程间切换要更高 —— 我估计这种开销还将持续提升。
面对大量连接,整个体系最终一定会因 TLB 未命中而浪费大量时间。
这是进程模型无法跨进程共享 TLB 的天然属性造成的必然结果。

目前这还仅仅只是一项提议,并且由于 PostgreSQL 被广泛用于生产环境,转换到线程模型的过程需要非常谨慎。开发团队需要在不影响现有生产环境的情况下测试新的线程模型,以确保其稳定性和可靠性。即便这个提议通过,这个转化过程肯定也是无法通过单一版本彻底完成,从网上的各方评价来看,目前大多数人都支持这项提议。

#894 那些个国际法院

2023-06-17

联合国国际法庭

International Court of Justice,ICJ

联合国六大主要机构之一和最主要的司法机关,是主权国家政府间的民事司法裁判机构,根据《联合国宪章》于 1945 年 6 月成立。

前身是国际联盟的常设国际法院(Permanent Court of International Justice)。

因为位于荷兰海牙,所以又叫海牙国际法庭。

官网:https://icj-cij.org/ch

PS:联合国另外五个主要机关:

  1. 联合国秘书处
  2. 联合国安理会
  3. 联合国大会
  4. 经济及社会理事会
  5. 联合国托管理事会

常设仲裁法院

Permanent Court of Arbitration,PCA

世界上现存最古老的国际仲裁机构。根据 1899 年《关于和平解决国际争端的海牙公约》(第一次海牙和平会议)以及 1907 年《和平解决国际争端的公约》(第二次海牙和平会议)成立。
中国在清朝的时候签署协议,成为缔约国。

总部位于海牙和平宫。PS:ICJ 成立之后,也在海牙和平宫办公。两个组织完全相互独立。

不只是处理国家之间的纠纷,还可以接受委托处理私人之间,或者国家和私人之间的一些纠纷。
不过实际上,该组织基本上没有怎么受理过案子,最近还是因为菲律宾控告中国案(南海仲裁案)而被人们注意到。

关于南海仲裁案

  1. 中方态度:常设仲裁法院对于领土问题没有司法管辖权,因此中国不接受、不参与仲裁(2013 年 2 月 19 日,中国正式拒绝参与仲裁案)。
  2. 2016 年 7 月 12 日,在中方全程没有参与的情况下,仲裁庭作出判决:中国对南海不存在历史性所有权,九段线不合法(民国时期是 11 段线),要求中国停止“填海造陆”。
  3. 五个法官中有四人是国际海洋法法庭现任或前任法官,菲律宾指派一位法官代表菲律宾,由于中方没有参加,剩余四人全部由国际海洋法法庭时任庭长柳井俊二指派。
  4. 和预期一样,欧美日澳,部分东盟国家支持仲裁,中国的国际外交基本盘支持中方立场。
  5. 仲裁期间,南海领域中美军事对峙。持续一段时间之后,美军航母自行撤离。
  6. 仲裁结束之后,新任菲律宾总统立即和中国恢复关系,不提此次仲裁。
  7. 联合国、国际法院、国际海洋法法庭先后发表声明,这次仲裁和他们没有关系。

国际刑事法院

International Criminal Court,ICC

根据 2002 年 7 月 1 日开始生效的《国际刑事法院罗马规约》成立。

同样总部位于荷兰海牙,其主要功能是对犯有灭绝种族罪、危害人类罪、战争罪、侵略罪的个人进行起诉和审判。

根据维基百科信息:有 123 个国家已经签署并批准该规约,成为国际刑事法院的成员国。有 31 个国家仅仅只是签署。
五个安理会常任理事国中,英法是成员国,中国没有签署,俄美先签署,随后立即撤回。

因为普京已经被 ICC 判战争罪,按理来说成员国有义务逮捕他。
然后本届金砖国家领导人峰会由 ICC 成员国南非举办,如何处理这个问题备受瞩目。

国家刑事警察组织

International Criminal Police Organization,ICPO
INTERPOL

除联合国之外,第二大国际组织。

和 ICC 没有关联,是国际警务合作的一个平台,主要责任为通报逃税、恐怖活动、有组织犯罪、毒品、走私军火、偷渡、洗钱、儿童色情、贪污和高科技犯罪等大型严重跨国犯罪,不过并无当地执法权。

国际海洋法法庭

International Tribunal for the Law of the Sea,ITLOS

根据《联合国海洋法公约》建立的一个法律组织。始建于 1996 年,总部位于德国汉堡市,是专门审理海洋法案件的国际组织。现为联合国大会观察员组织。

国际仲裁法庭

International Court of Arbitration

国际商会(International Chamber of Commerce)(总部位于巴黎)下属仲裁服务的机构。
不要和 PCA 搞混淆了。

#893 CPU 架构

2023-06-12

OSChina 上发布的资讯《Debian 13 “Trixie” 将提供 RISC-V 64 位支持》中提到:

最新发布的 Debian 12 支持九种架构: AMD64、AArch64、ARMEL、ARMHF、i386、MIPS、64 位 MIPS、POWER 和 IBM System Z。

这应该是现在最流行的 CPU 架构了吧。

  • x86_64
  • AMD64
  • i386
  • ARM
  • AArch64
  • ARMEL:Little Endian
  • ARMHF:Hard Float,使用硬件浮点寄存器和指令来提高计算性能
  • MIPS
  • MIPS
  • MIPS64
  • POWER
  • IBM System Z
  • RISC-V

#892 爸小猪故事

2023-06-11

从前,有三只可爱的小猪,它们是一家的兄弟姐妹。老大哥哥叫皮鲁,老二妹妹叫皮娜,老三弟弟叫皮休。他们住在一个美丽的森林中,一起快乐地生活着。

#891 头上的辫子与心里的辫子

2023-06-11

假发

近日有新闻讨论香港法官至今保留原宗主国戴假发的传统(陋习)。

先说一下我对这个司法假发的一点了解。
16 世纪,欧洲贵族社会性病流行,其中症状之一就是脱发严重。于是,随着时间的流逝,上层社会戴假发的习俗慢慢演化成了地位的象征。
医疗技术发展起来之后,带假发的这种习俗就迅速消亡了,谁会喜欢没事带着这么个劳什子呢,想想都不舒服嘛。

不过,因为英国有立法,规定法律从业人士的着装要求,其中就包括必须戴假发(WTF)。
一种长发及肩,用在刑法庭,一种短些,用在民法庭。

PS:可以搜索一下带假发的法官图片,简直丑的一批,我想应该是没有人会喜欢这玩意儿吧。
PS:美国第三任总统托马斯·杰斐逊:“(英国法官)像躲在棉絮下面向外窥视的老鼠”。

因为英国到处侵略与殖民,将本国的法律推及到很多地方,包括中国香港。
所以,部分地区的司法界保留了这个传统直到近代。

根据维基百科的信息,英国、加拿大、澳大利亚、新西兰已经部分废除了假发在法庭中的使用。但香港司法界至今坚持必须戴假发上庭。
我对司法制度不了解,但是这个假发就是一个配饰,完全无关司法精神吧,为什么必须用法律法规来强制佩戴呢?
这个和清朝遗民舍不得辫子是何其相识!

辫子

说到辫子,不禁想起了《建党大业》中,辜鸿铭的经典台词:“我的辫子长在脑后,笑我的人,辫子长在心头。老夫头上的辫子是有形的,而诸公心中的辫子却是无形的。”
这句话说的其实也挺在理的,因为比人家弱,就什么都要跟人家学习,觉得自己家什么都是糟粕,这何尝不是辫子长在心头呢!
辫子就是不自信,就是觉得自己低人一头,就是外国的月亮比较圆。

假发是外在的辫子,皇民心态是内在的辫子。而我们希望他们能彻底抹除原宗主国的痕迹,有没有一点辫子的意味呢?
我的意思是,从发展的眼光看问题,他们这顶可笑的假发早晚是会消失的,但我们是否过于着急了,这种心态是不是对于过去的屈辱历史过于耿耿于怀了,算不算文化上的不自信呢?

参考资料与拓展阅读

#890 关于自托管邮件服务

2023-06-10

看到科技爱好者周刊推荐的一篇文章,介绍了自托管邮件服务的一些现状,主要是 Gmail 这样的主流邮箱服务提供商(MSP)拒收来自自托管邮件服务的邮件(或标记成垃圾邮件),导致自托管邮件服务的运营遇到很大的困难。

电子邮件在因特网没有出现之前就已经诞生,简单、开放,易于开发和使用,人人都能成为 Email 网络中的一个节点。实际上,大部分人都是使用的一些大 MSP 的服务,但也有部分人(或者组织)使用的是自己部署的邮件服务。他们会发现哪怕所有应该做的都做了,比如 SPF,DKIM,DMARC,他们的邮件还是经常无法正常投递出去(被拒、限流等),或者在收件人的垃圾文件夹中。

在一定程度上,MSP 的做法也是可以理解的,垃圾邮件泛滥成灾,确实防不胜防。因为邮件服务本身是毫无门槛。除非上一个手机实名制这样的严格管控,或许能解决这个问题。

文章提出的主要价值点是,什么情况下我们有必要自建邮箱服务?

  1. 准备好投入很多时间和精力来维护这套系统
  2. 搭建系统
  3. 留意 SPF 和 DMARC 报告
  4. 有服务器管理能力(Linux,Docker)
  5. ISP 支持开放 25、143、465、587、993 端口
  6. 静态 IP + rDNS 配置权限
  7. 一个合适的域名

#889 gotip 命令

2023-05-30

gotip 是官方推出的,从最新的开发分支下拉代码,编译生成 go 运行时的工具。
如果希望体验最新特性,可以在编译成功之后,可以直接用 gotip 取代 go 命令用来执行 go 程序。
gotip 就可以理解为开发版的 go。

go install golang.org/dl/gotip@latest

gotip
gotip: not downloaded. Run 'gotip download' to install to C:\Users\nosch\sdk\gotip

gotip download
Cloning into 'C:\Users\nosch\sdk\gotip'...
...
Building Go cmd/dist using C:\Program Files\Go. (go1.20.5 windows/amd64)
Building Go toolchain1 using C:\Program Files\Go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for windows/amd64.

成功的时候:
---
Installed Go for windows/amd64 in C:\Users\nosch\sdk\gotip
Installed commands in C:\Users\nosch\sdk\gotip
Success. You may now run 'gotip'!

失败的时候:
# runtime/cgo
gcc_libinit_windows.c: In function '_cgo_beginthread':
gcc_libinit_windows.c:143:27: error: implicit declaration of function '_beginthread'; did you mean '_cgo_beginthread'? [-Werror=implicit-function-declaration]
  143 |                 thandle = _beginthread(func, 0, arg);
      |                           ^~~~~~~~~~~~
      |                           _cgo_beginthread
cc1: all warnings being treated as errors
go tool dist: FAILED: C:\Users\nosch\sdk\gotip\pkg\tool\windows_amd64\go_bootstrap install std: exit status 1
Success. You may now run 'gotip'!

#888 Go set 类型

2023-05-29

Go 并没有支持集合类型,我们需要自己实现:

https://go.dev/play/p/uVDCiN4Cbpt

package main

import "fmt"

type Set map[string]bool

func (s Set) Add(item string) {
    s[item] = true
}

func (s Set) Remove(item string) {
    delete(s, item)
}

func (s Set) Contains(item string) bool {
    _, exists := s[item]
    return exists
}

func main() {
    mySet := make(Set)
    mySet.Add("apple")
    mySet.Add("banana")
    mySet.Add("orange")

    for item := range mySet {
        fmt.Println(item)
    }

    fmt.Println(mySet.Contains("apple")) // 输出: true
    fmt.Println(mySet.Contains("grape")) // 输出: false

    mySet.Remove("banana")
    fmt.Println(mySet.Contains("banana")) // 输出: false
}

注意:

  1. 使用 map 做底层存储,因此实现的 set 也是无序的
  2. map 不是线程安全的,如果有并发操作,需要加锁
  3. 如果真的要使用集合类型,应该再扩充一下交集,差集等方法

改进

参考 https://github.com/deckarep/golang-set 的设计:

https://go.dev/play/p/BKWT84lXfuz

package main

import "fmt"

type Set[T comparable] map[T]struct{}

func (s Set[T]) Add(item T) {
    s[item] = struct{}{}
}

func (s Set[T]) Remove(item T) {
    delete(s, item)
}

func (s Set[T]) Contains(item T) bool {
    _, exists := s[item]
    return exists
}

func main() {
    mySet := make(Set[string])
    mySet.Add("apple")
    mySet.Add("banana")
    mySet.Add("orange")

    for item := range mySet {
        fmt.Println(item)
    }

    fmt.Println(mySet.Contains("apple")) // 输出: true
    fmt.Println(mySet.Contains("grape")) // 输出: false

    mySet.Remove("banana")
    fmt.Println(mySet.Contains("banana")) // 输出: false
}

优化点

  1. 空结构体不占空间
  2. 泛型让代码复用性更好