离线编译etcd
① go语言可以做什么
go语言在高性能分布式系统领域有很好的开发效率,可以主要用于服务器端的开发,能够进行处理日志、数据打包、虚拟机处理、文件系统、分布式系统、数据库代理等。
Go(又称Golang)是Google的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与C相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style并发计算。
撰写风格:
在Go中有几项规定,当不匹配以下规定时编译将会产生错误。
每行程序结束后不需要撰写分号(;)。
大括号({)不能够换行放置。
if判断式和for循环不需要以小括号包覆起来。
Go亦有内置gofmt工具,能够自动整理代码多余的空白、变量名称对齐、并将对齐空格转换成Tab。
② kong网关怎么获取etcd端口
etcd简介与应用场景 etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与...
2.
单机模式运行 默认在centos7的yum源里已集成了etcd包,可以通过携指yum进行安装...
3.
集群模式说明 这里的集群模式是指完全集群模式,当然也可桥脊以在单机上通过不同的端口,部署伪...
4.
静态模式 如果只是测试,这里建议使辩消配用二进制包进行测试。因为源码包编译的,使用etcd命令...
5.
动态配置 静态配置前提是在搭建集群之前已经提前知道各节点的信息,而实际应用中可能
③ k8s的Mutating webhook
Admission Webhook 是 api-server 对外提供的一个扩展能力,api-server 作为 kubernetes 的核心,几乎所有组件都需要跟他打交道,基本可以说掌控了 k8s 的 api-server,你就可以控制 k8s 的行为。
在早期的版本 api-server 并没有提供 admissionresgistration 的能力(v1.9之前),当我们要对 k8s 进行控制的时候,只能重新编译 api-server。比如你想阻止某个控制器的行为,或拦截某个控制器的资源修改。admission webhook 就是提供了这样的能力,比如你芹姿希望某个特定 label 标兆首态签的 pod 再创建的时候都注入 sidercar,或者阻止不合规的资源。
Admission Webhook 包涵两种 CRD: mutatingwebhookconfiguration 和 。
下面是一个 mutatingwebhookconfiguration 的CRD文件:
Admission Webhook 本质是 api-server 的一个 webhook 调用,下面是 api-server 的处理流程:
api-server 通过读取 mutatingwebhookconfiguration 和 的 CR 文件的目标地址,然后回调用户自定义的服务。
api-server 发起的请求是一串json数据格式,header需要设置 content-type 为 application/json , 我们看看请求的 body :
返回的结果:
这里的 patch 是用base64编码的一个json,我们解码看看,是一个 json patch:
处理函数:
主程序:
基于私钥生成一个证书签名请求(Certificate Signing Request,CSR),目标地址的域名为: mutating-test.testing-tools.svc , csr的配置:
创建命令:
基于csr创建 CertificateSigningRequest :
认证完成可以查看:
生成证书:
获取api-server的CA证书:
将这个证书填入 Webhook 的 caBundle。
MutatingAdmissionWebhook作为kubernetes的ApiServer中Admission Controller的一部分,提供了非常灵活的扩展机制,通过配置MutatingWebhookConfiguration对象,理论上可以监听并修改任何经过ApiServer处理的请求
MutatingWebhookConfiguration是kubernetes的一个官方的资源提供的对象,下面对该对象的字段做一些简单的说明:
结合rules.operations和rules.resources的属性,我们可以知道样例中的MutatingWebhookConfiguration监听了集群中nodes资源的status数据向apiServer提交的更新操作(就是我们前面提到的心跳信息),并且将所有的心跳信息发给了名为webhook-oversale-service的Service下的/mutate接口处理,这个接口就是我们自定义的webhook服务提供的。
上图中的Pod跑着的容器就是我们自定义的webhook服务,一个自定义webhook服务样例供参考
在生产环境中,kubernetes集群的计算节点上运行着许许多多的Pod,分别跑着各种业务容器,我们通常用Deployment、DeamonSet、StatefulSet等资源对象去控制Pod的增删改。因此族源,开发或运维往往需要配置这些资源对象的Containers字段中业务容器的CPU和内存的资源配额:requests和limit
requests:节点调度pod需要的资源,每次成功调度则将节点的Allocatable属性值(可分配资源)重新计算,
新的Allocatable值 = 旧的Allocatable值 - 设置的requests值
limit:节点中运行pod能够获得的最大资源,当cpu
我们不难发现,当requests字段设置太大的时候,pod实际使用的资源却很小,导致计算节点的Allocatable值很快就被消耗完,节点的资源利用率会变得很低。
上图中最大的蓝色框(allocatable)为计算节点可分配资源,橙色框(requests)为用户配置的requests属性,红色框(current)为业务容器实际使用的资源。因此节点的资源利用率为 current / allocatable。而由于requests设置太大,占满了allocatable,导致新的pod无法被调度到这个节点,就会出现节点实际资源占用很低,却因为allocatable太低导致pod无法调度到该节点的现象。
因此我们能否通过动态调整allocatable的值来让计算节点的可分配资源变得"虚高",骗过k8s的调度器,让它以为该节点可分配资源很大,让尽可能多的pod调度到该节点上呢?
上图通过将allocatable值扩大(fake allcatable),让更多的pod调度到了改节点,节点的资源利用率 current / allocatable 就变大了。
实现资源超卖的关键在于动态修改节点Node对象的allocatable字段值,而我们看到allocatable字段属于Status字段,显然不能直接通过kubectl edit命令来直接修改。因为Status字段和Spec字段不同,Spec是用户设置的期望数据,而Status是实际数据(Node节点通过不断向apiServer发送心跳来更新自己的实时状态,最终存在etcd中)。那么我们要怎么去修改Stauts字段呢?
首先,要修改k8s中任何资源对象的Status值,k8s官方提供了一套RESTful API: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13
可以通过patch或者put方法来调用k8s的RESTful API,实现Stauts字段的修改。(这里是通过ApiServer去修改etcd中保存的Status字段的值)
但是,Node资源对象比较特殊,计算节点会不断给ApiServer发送心跳(默认每隔10s发一次),将带有Status字段的真实信息发送给ApiServer,并更新到etcd中。也就是无论你怎么通过patch/put方法去修改Node的Status字段,计算节点都会定时通过发送心跳将真实的Status数据覆盖你修改的数据,也就是说我们无法通过直接调用RESTful API修改Node对象中的Status数据。
那我们是否可以直接监听这个计算节点的心跳数据,通过修改心跳数据中的Status字段中的allocatable值,从而实现资源超卖呢?
答案是肯定的,k8s在ApiServer中就提供了Admission Controller(准入控制器)的机制,其中包括了MutatingAdmissionWebhook,通过这个webhook,所有和集群中所有和ApiSever交互的请求都被发送到一个指定的接口中,我们只要提供一个这样的接口,就可以获取到Node往ApiServer发送心跳的Staus数据了。然后将这个数据进行我们的自定义修改,再往后传给etcd,就能让etcd以为我们修改过的Status数据就是节点的真实Status,最终实现资源的超卖。
我们都知道,Istio的流量管理、策略、遥测等功能无须应用程序做任何改动,这种无侵入式的方式全部依赖于Sidecar。应用程序发送或者接收的流量都被Sidecar拦截,并由Sidecar进行认证、鉴权、策略执行及遥测数据上报等众多治理功能。
如图所示,在Kubernetes中,Sidecar容器与应用容器共存于同一个Pod中,并且共享同一个Network Namespaces,因此Sidecar容器与应用容器共享同一个网络协议栈,这也是Sidecar能够通过iptables拦截应用进出口流量的根本原因。
Istio的Sidecar模式
在Istio中进行Sidecar注入有两种方式:一种是通过istioctl命令行工具手动注入;另一种是通Istio Sidecar Injector自动注入。
这两种方式的最终目的都是在应用Pod中注入init容器及istio-proxy容器这两个Sidecar容器。如下所示,通过部署Istio的sleep应用,Sidecar是通过sidecar-injector自动注入的,查看注入的Sidecar容器:
Sidecar Injector是Istio中实现自动注入Sidecar的组件,它是以Kubernetes准入控制器Admission Controller的形式运行的。Admission Controller的基本工作原理是拦截Kube-apiserver的请求,在对象持久化之前、认证鉴权之后进行拦截。Admission Controller有两种:一种是内置的,另一种是用户自定义的。Kubernetes允许用户以Webhook的方式自定义准入控制器,Sidecar Injector就是这样一种特殊的MutatingAdmissionWebhook。
如图所示,Sidecar Injector只在创建Pod时进行Sidecar容器注入,在Pod的创建请求到达Kube-apiserver后,首先进行认证鉴权,然后在准入控制阶段,Kube-apiserver以REST的方式同步调用Sidecar Injector Webhook服务进行init与istio-proxy容器的注入,最后将Pod对象持久化存储到etcd中。
Sidecar Injector可以通过MutatingWebhookConfiguration API动态配置生效,Istio中的MutatingWebhook配置如下:
从以上配置可知,Sidecar Injector只对标签匹配“istio-injection: enabled”的命名空间下的Pod资源对象的创建生效。Webhook服务的访问路径为“/inject”,地址及访问凭证等都在clientConfig字段下进行配置。
Istio Sidecar Injector组件是由sidecar-injector进程实现的,本书在之后将二者视为同一概念。Sidecar Injector的实现主要由两部分组成:
MutatingWebhookConfiguration对象的维护主要指监听本地证书的变化及Kubernetes MutatingWebhookConfiguration资源的变化,以检查CA证书或者CA数据是否有更新,并且在本地CA证书与MutatingWebhookConfiguration中的CA证书不一致时,自动更新MutatingWebhookConfiguration对象。
④ go mod如何手动替换包
之前在项目中遇到过etcd的版本不一致, 导致无法编译贺败. 最终是因为版本不一码激致的问题。
先删除vendor: rm -rf vendor 或手动删除。1.再替版本: go mod edit -require=google.golang.org/[email protected]。2.下载指定版本v1.26.0: go get -u -x google.golang.org/[email protected]。3.然后再go mod vendor。迟拍袜
⑤ K3S 离线安装部署高可用集群
执行范围:所有主机
执行完成后重启服务器。
执行范围: 所有主机
安装方式: 二进制离线安装
执行范围: 所有主机
作用:用于为k3s提供存储,k3s支持除etcd外的集群数据存储方式
执行范围: 10.2.2.10 服务器主机
说明:选用5.7版本是因为该版本是rancher官方推荐。
第5步中,只需要对server节点所在的IP创建用户并授权就可以了。
对于server-1 10.2.2.13节点
对于server-2 10.2.2.14节点
两个server节点部署完成后,查看当前集群节点状况
1、haproxy的部署和配置
部署 haproxy-2.4.7
部署方式:二进制
执行范围:10.2.2.11 10.2.2.12 (两台服务器操作完全一致)
访问haproxy-UI http://10.2.2.11:18090/admin 监控页面
2、 keepalived的部署和配置
部署 keepalived-2.1.5
部署方式:二进制
执行范围:10.2.2.11 10.2.2.12 (两台服务器keepalived配置文件有所差异,下文会标明)
3、通过keepalived虚拟VIP http://10.2.2.100:18090/admin 访问haproxy监控页面
执行范围: 10.2.2.15 10.2.2.16
登录10.2.2.13(即上述server-1节点),拷贝k3s的3个文件到10.2.2.15和10.2.2.16两台主机上
修改install.sh文件,如下(10.2.2.15和10.2.2.16改动都一样)
安装
登录10.2.2.13查看集群节点
九、安装rancher-ui界面
操作范围:10.2.2.10
访问
继续按下图所示导入k3s集群到rancher
⑥ Golang项目部署3,容器部署
容器部署即使用 docker 化部署 golang 应用程序,这是在云服务时代最流行的部署方式,也是最推荐的部署方式。
跨平台交叉编译是 golang 的特点之一,可以非常方便地编译出我们需要的目标服务器平台的版本,而且是静态编译,非常容易地解决了运行依赖问题。
使用以下指令可以静态编译 Linux 平台 amd64 架构的可执行文件:
生成的 main 便是我们静态编译的,可部署于 Linux amd64 上的可执行文件。
我们需要将该可执行文件 main 编译生成 docker 镜像,以便于分发及部署。 Golang 的运行环境推荐使用 alpine 基础系统镜像,编译出的容器镜像约为 20MB 左右。
一个参考的 Dockerfile 文件如下:
其中,我们的基础镜像使用了 loads/alpine:3.8 ,中国国内的消正用户推荐使用该基础镜像,基础镜像的 Dockerfile 地址: https://github.com/johngcn/dockerfiles ,仓库地址: https://hub.docker.com/u/loads
随后使用 " docker build -t main . " 指令编译生成名为 main 的 docker 镜像。
需要注意的是,在某些项目的架构设计中, 静态文轿轮件 和 配置文件 可能不会随着镜像进行编译发布,而是分开进行管理和发布。
例如,使用 MVVM 模式的项目中(例如使用 vue 框架),往往是前后端非常独立的,因此在镜像中往往并不会包含 public 目录。而使用了 配置管理中心 (例如使用 consul / etcd / zookeeper )的项目中,也往往并不需要 config 目拿帆悔录。
因此对于以上示例的 Dockerfile 的使用,仅作参考,根据实际情况请进行必要的调整。
使用以下指令可直接运行刚才编译成的镜像:
容器的分发可以使用 docker 官方的平台: https://hub.docker.com/ ,国内也可以考虑使用阿里云: https://www.aliyun.com/proct/acr 。
在企业级生产环境中, docker 容器往往需要结合 kubernetes 或者 docker swarm 容器编排工具一起使用。
容器编排涉及到的内容比较多,感兴趣的同学可以参考以下资料:
⑦ golang有没有好的开源游戏框架
为什么golang的开发效率高?</ol>golang是一编译型的强类型语言,它在开发上的高效率主要来自于后发优势,不用考虑旧有恶心的历史,又有一个较高的工程视角。良好的避免了程序员因为“ { 需不需要独占一行 ”这种革命问题打架,也解决了一部分趁编译时间找产品妹妹搭讪的阶级敌人。
它有自己的包管理机制,工具链成熟,从开发、调试到发布都很简单方便;有反向接口、defer、coroutine等大量的syntactic sugar;编译速度快,因为是强类型语言又有gc,只要通过编译,非业务毛病就很少了;它在语法级别上支持了goroutine,这是大家说到最多的内容,这里重点提一下。首先,coroutine并不稀罕,语言并不能超越硬件、操作系统实现神乎其神的功能。golang可以做到事情,其他语言也可以做到,譬如c++,在boost库里面自己就有的coroutine实现(当然用起来跟其他boost库一样恶心)。golang做的事情,是把这一套东西的使用过程简化了,并且提供了一套channel的通信模式,使得程序员可以忽略诸如死锁等问题。
goroutine的目的是描述并发编程模型。并发与并行不同,它并不需要多核的硬件支持,它不是一种物理运行状态,而是一种程序逻辑流程。它的主要目的不是利用多核提高运行效率,而是提供一种更容易理解、不容易出错的语言来描述问题。
实际上golang默认就是运行在单OS进程上面的,通过指定环境变量GOMAXPROCS才能转身跑在多OS进程上面。有人提到了的pomelo,开源本来是一件很不错的事情,但是基于自己对callback hell的偏见,我一直持有这种态度:敢用nodejs写大规模游戏服务器的人,都是真正的勇士 : ) 。
2、Erlang与Golang的coroutine有啥区别,coroutine是啥?
coroutine本质上是语言开发者自己实现的、处于user space内的线程,无论是erlang、还是golang都是这样。需要解决没有时钟中断;碰着阻塞式i\o,整个进程都会被操作系统主动挂起;需要自己拥有调度控制能力(放在并行环境下面还是挺麻烦的一件事)等等问题。那为啥要废老大的劲自己做一套线程放user space里面呢?并发是服务器语言必须要解决的问题;system space的进程还有线程调度都太慢了、占用的空间也太大了。把线程放到user space的可以避免了陷入system call进行上下文切换以及高速缓冲更新,线程本身以及切换等操作可以做得非常的轻量。这也就是golang这类语言反复提及的超高并发能力,分分钟给你开上几千个线程不费力。
不同的是,golang的并发调度在i/o等易发阻塞的时候才会发生,一般是内封在库函数内;erlang则更夸张,对每个coroutine维持一个计数器,常用语句都会导致这个计数器进行rection,一旦到点,立即切换调度函数。
中断介入程度的不同,导致erlang看上去拥有了preemptive scheling的能力,而golang则是cooperative shceling的。golang一旦写出纯计算死猜弯耐循环,进程内所有会话必死无疑;要有大计算量少i\o的函数还得自己主动叫runtime.Sched()来进行调度切换。
3、golang的运行效率怎么样?
我是相当反感所谓的ping\pong式benchmark,运行效率需要放到具体的工作环境下面考虑。
首先,它再快也是快不过c的,毕竟底下做了那么多工作,又有调度,又有gc什么的。穗春那为什么在那些benchmark里面,golang、nodejs、erlang的响应效率看上去那么优秀呢,响应快,并发强?并发能力强的原因上面已经提到了,响应快是因为大量非阻塞式i\o操作出现的原因。这一点c也可以做到,并且能力更强,但是得多写不少优质代码。
然后,针对游戏服务器这种高实时性的运行环境,GC所造成的跳帧问题确实比较麻烦,前面的大神 @达达 有比较详细的论述和缓解方案,就不累述了 。随着golang的持续开发,相信应该会有非常大的改进。一是屏蔽内存操作是现代语言的大势所趋,它肯定是需要被实现的;二是GC算法已经相当的成熟,效率勉勉强强过得去;三是闹孝可以通过incremental的操作来均摊cpu消耗。
用这一点点效率损失换取一个更高的生产能力是不是值得呢?我觉得是值得的,硬件已经很便宜了,人生苦短,让自己的生活更轻松一点吧: )。
4、基于以上的论述,我认为采用go进行小范围的MMORPG开发是可行的。
⑧ pgsql的主键存储方式
PostgreSQL的稳定性极强,Innodb等索引在崩溃,断电之类的灾难场景下 抗击打能力有了长足进步,然而很多 MqSQL用户 都遇到过 Server级的数据库丢失的场景 -- MySQL系统库是 MyISAM,相比之下,PG数据库这方面要更好一些。
任何系统都有它的性能极限,在高并发读写,负载逼近极限下,PG的性能指标仍可以位置双曲线甚至对数曲线,到 顶峰之后不在下降,而MySQL明显出现一个波峰后下滑(5.5版本 之后,在企业级版本中有个插件可以改善很多,不过需要付费)。
PG多年来在 GIS(地理信息)领域处于优势地位,因为它有丰富的几何类型,PG有大量字典,数组,bitmap等数据类型,相比之下 MySQL就差很多, Instagram就是因为 PG的空间数据库 扩展 POSTGIS远远强于 MySQL的 my spatial 而采用 PgSQL的。
PG的“无锁定”特性非常突出,甚至包括 vacuum这样的整理数据空间的操作,这个和PGSQL的MVCC实现有关系。
PG可以使用函数 和 条件索引,这使得 PG数据库的调优非常灵活, MySQL就没有这个功能,条件索引在 web应用中 很重要。
PG有极其强悍的 SQL编程能力(9.x 图灵完备,支持递归!),有非常丰富的统计函数和统计语法支持,比如分析函数(Oracle的叫法,PG里叫Window函数),还可以用多种语言来写存储过程,对于 R的支持也很好。这一点MySQL就差很多,很多分析功能都不支持,腾讯内部的存储主要是 MySQL,但是数据分析主要是 Hadoop+ PgSQL。
PG的有多种集群架构可以选择,plproxy可以之hi语句级的镜像或分片,slony可以进行字段级的同步配置,standby 可以构建 WAL文件级或流式的读写分离集群,同步频率和集群策略调整方便。
一般关系型数据库字符串有长度限制 8k 左右,无限长 TEXT类型的功能受限,只能作为外部大数据访问。而 PG 的 TEXT 类型 可以直接访问且无长度限制, SQL语法内置 正则表达式,可以索引,还可以全文检索,或使用 xml xpath。用 PG的话,文档数据库都可以省了。
PgSQL对于 numa 架构的支持比 MySQL强一些,比 MySQL对于读的性能更好一些, PgSQL提交可以完全异步提交,而 MySQL的内存表不够实用(因为表锁的原因)。
pgsql除了存储正常的数据类型外,还支持存储
array,不管是一维数组还是多维数组均支持。
json和jsonb,相比使用 text存储要高效很多。
json和 jsonb在更高的层面上看起来几乎是一样的,但是存储实现上是不同的。
json存储完的文本,json列会每次都解析存储的值,它不支持索引,但 可以为创建表达式索引。
jsonb存储的二进制格式,避免了重新解析数据结构。它支持索引,这意味着 可以不使用指定索引就能查询任何路径。
当我们比较写入数据速度时,由于数据存储 的方式的原因,jsonb会比 json 稍微的慢一点。json列会每次都 解析存储的值,这意味着键的顺序要和输入的 时候一样。但是 jsonb不同,以二进制格式存储且不保证键的顺序。因此如果有软件需要依赖键的顺序,jsonb可能不是最佳选择。使用 jsonb的优势还在于可以轻易的整合关系型数据和非关系型 数据 ,PostgreSQL对于 mongodb这类数据库是一个不小的威胁,毕竟如果一个表中只有一列数据的类型是半结构化的,没有必要为了迁就它而整个表的设计都采用 schemaless的结构。
1. CPU限制
PGSQL
没有CPU核心数限制,有多少CPU核就用多少
MySQL
能用128核CPU,超过128核用不上
2. 配置文件参数
PGSQL
一共有255个参数,用到的大概是80个,参数比较稳定,用上个大版本配置文件也可以启动当前大版本数据库
MySQL
一共有707个参数,用到的大概是180个,参数不断增加,就算小版本也会增加参数,大版本之间会有部分参数不兼容情况
3. 第三方工具依赖情况
PGSQL
只有高可用集群需要依靠第三方中间件,例如:patroni+etcd、repmgr
MySQL
大部分操作都要依靠percona公司的第三方工具(percona-toolkit,XtraBackup),工具命令太多,学习成本高,高可用集群也需要第三方中间件,官方MGR集群还没成熟
4. 高可用主从复制底层原理
PGSQL
物理流复制,属于物理复制,跟SQL Server镜像/AlwaysOn一样,严格一致,没有任何可能导致不一致,性能和可靠性上,物理复制完胜逻辑复制,维护简单
MySQL
主从复制,属于逻辑复制,(sql_log_bin、binlog_format等参数设置不正确都会导致主从不一致)
大事务并行复制效率低,对于重要业务,需要依赖 percona-toolkit的pt-table-checksum和pt-table-sync工具定期比较和修复主从一致
主从复制出错严重时候需要重搭主从
MySQL的逻辑复制并不阻止两个不一致的数据库建立复制关系
5. 从库只读状态
PGSQL
系统自动设置从库默认只读,不需要人工介入,维护简单
MySQL
从库需要手动设置参数super_read_only=on,让从库设置为只读,super_read_only参数有bug,链接:https://jiahao..com/s?id=1636644783594388753&wfr=spider&for=pc
6. 版本分支
PGSQL
只有社区版,没有其他任何分支版本,PGSQL官方统一开发,统一维护,社区版有所有功能,不像SQL Server和MySQL有标准版、企业版、经典版、社区版、开发版、web版之分
国内外还有一些基于PGSQL做二次开发的数据库厂商,例如:Enterprise DB、瀚高数据库等等,当然这些只是二次开发并不算独立分支
MySQL
由于历史原因,分裂为三个分支版本,MariaDB分支、Percona分支 、Oracle官方分支,发展到目前为止各个分支基本互相不兼容
Oracle官方分支还有版本之分,分为标准版、企业版、经典版、社区版
7. SQL特性支持
PGSQL
SQL特性支持情况支持94种,SQL语法支持最完善,例如:支持公用表表达式(WITH查询)
MySQL
SQL特性支持情况支持36种,SQL语法支持比较弱,例如:不支持公用表表达式(WITH查询)
关于SQL特性支持情况的对比,可以参考:http://www.sql-workbench.net/dbms_comparison.html
8. 主从复制安全性
PGSQL
同步流复制、强同步(remote apply)、高安全,不会丢数据
PGSQL同步流复制:所有从库宕机,主库会罢工,主库无法自动切换为异步流复制(异步模式),需要通过增加从库数量来解决,一般生产环境至少有两个从库
手动解决:在PG主库修改参数synchronous_standby_names ='',并执行命令: pgctl reload ,把主库切换为异步模式
主从数据完全一致是高可用切换的第一前提,所以PGSQL选择主库罢工也是可以理解
MySQL
增强半同步复制 ,mysql5.7版本增强半同步才能保证主从复制时候不丢数据
mysql5.7半同步复制相关参数:
参数rpl_semi_sync_master_wait_for_slave_count 等待至少多少个从库接收到binlog,主库才提交事务,一般设置为1,性能最高
参数rpl_semi_sync_master_timeout 等待多少毫秒,从库无回应自动切换为异步模式,一般设置为无限大,不让主库自动切换为异步模式
所有从库宕机,主库会罢工,因为无法收到任何从库的应答包
手动解决:在MySQL主库修改参数rpl_semi_sync_master_wait_for_slave_count=0
9. 多字段统计信息
PGSQL
支持多字段统计信息
MySQL
不支持多字段统计信息
10. 索引类型
PGSQL
多种索引类型(btree , hash , gin , gist , sp-gist , brin , bloom , rum , zombodb , bitmap,部分索引,表达式索引)
MySQL
btree 索引,全文索引(低效),表达式索引(需要建虚拟列),hash 索引只在内存表
11. 物理表连接算法
PGSQL
支持 nested-loop join 、hash join 、merge join
MySQL
只支持 nested-loop join
12. 子查询和视图性能
PGSQL
子查询,视图优化,性能比较高
MySQL
视图谓词条件下推限制多,子查询上拉限制多
13. 执行计划即时编译
PGSQL
支持 JIT 执行计划即时编译,使用LLVM编译器
MySQL
不支持执行计划即时编译
14. 并行查询
PGSQL
并行查询(多种并行查询优化方法),并行查询一般多见于商业数据库,是重量级功能
MySQL
有限,只支持主键并行查询
15. 物化视图
PGSQL
支持物化视图
MySQL
不支持物化视图
16. 插件功能
PGSQL
支持插件功能,可以丰富PGSQL的功能,GIS地理插件,时序数据库插件, 向量化执行插件等等
MySQL
不支持插件功能
17. check约束
PGSQL
支持check约束
MySQL
不支持check约束,可以写check约束,但存储引擎会忽略它的作用,因此check约束并不起作用(mariadb 支持)
18. gpu 加速SQL
PGSQL
可以使用gpu 加速SQL的执行速度
MySQL
不支持gpu 加速SQL 的执行速度
19. 数据类型
PGSQL
数据类型丰富,如 ltree,hstore,数组类型,ip类型,text类型,有了text类型不再需要varchar,text类型字段最大存储1GB
MySQL
数据类型不够丰富
20. 跨库查询
PGSQL
不支持跨库查询,这个跟Oracle 12C以前一样
MySQL
可以跨库查询
21. 备份还原
PGSQL
备份还原非常简单,时点还原操作比SQL Server还要简单,完整备份+wal归档备份(增量)
假如有一个三节点的PGSQL主从集群,可以随便在其中一个节点做完整备份和wal归档备份
MySQL
备份还原相对不太简单,完整备份+binlog备份(增量)
完整备份需要percona的XtraBackup工具做物理备份,MySQL本身不支持物理备份
时点还原操作步骤繁琐复杂
22. 性能视图
PGSQL
需要安装pg_stat_statements插件,pg_stat_statements插件提供了丰富的性能视图:如:等待事件,系统统计信息等
不好的地方是,安装插件需要重启数据库,并且需要收集性能信息的数据库需要执行一个命令:create extension pg_stat_statements命令
否则不会收集任何性能信息,比较麻烦
MySQL
自带PS库,默认很多功能没有打开,而且打开PS库的性能视图功能对性能有影响(如:内存占用导致OOM bug)
23. 安装方式
PGSQL
有各个平台的包rpm包,deb包等等,相比MySQL缺少了二进制包,一般用源码编译安装,安装时间会长一些,执行命令多一些
MySQL
有各个平台的包rpm包,deb包等等,源码编译安装、二进制包安装,一般用二进制包安装,方便快捷
24. DDL操作
PGSQL
加字段、可变长字段类型长度改大不会锁表,所有的DDL操作都不需要借助第三方工具,并且跟商业数据库一样,DDL操作可以回滚,保证事务一致性
MySQL
由于大部分DDL操作都会锁表,例如加字段、可变长字段类型长度改大,所以需要借助percona-toolkit里面的pt-online-schema-change工具去完成操作
将影响减少到最低,特别是对大表进行DDL操作
DDL操作不能回滚
25. 大版本发布速度
PGSQL
PGSQL每年一个大版本发布,大版本发布的第二年就可以上生产环境,版本迭代速度很快
PGSQL 9.6正式版推出时间:2016年
PGSQL 10 正式版推出时间:2017年
PGSQL 11 正式版推出时间:2018年
PGSQL 12 正式版推出时间:2019年
MySQL
MySQL的大版本发布一般是2年~3年,一般大版本发布后的第二年才可以上生产环境,避免有坑,版本发布速度比较慢
MySQL5.5正式版推出时间:2010年
MySQL5.6正式版推出时间:2013年
MySQL5.7正式版推出时间:2015年
MySQL8.0正式版推出时间:2018年
26. returning语法
PGSQL
支持returning语法,returning clause 支持 DML 返回 Resultset,减少一次 Client <-> DB Server 交互
MySQL
不支持returning语法
27. 内部架构
PGSQL
多进程架构,并发连接数不能太多,跟Oracle一样,既然跟Oracle一样,那么很多优化方法也是相通的,例如:开启大页内存
MySQL
多线程架构,虽然多线程架构,但是官方有限制连接数,原因是系统的并发度是有限的,线程数太多,反而系统的处理能力下降,随着连接数上升,反而性能下降
一般同时只能处理200 ~300个数据库连接
28. 聚集索引
PGSQL
不支持聚集索引,PGSQL本身的MVCC的实现机制所导致
MySQL
支持聚集索引
29. 空闲事务终结功能
PGSQL
通过设置 idle_in_transaction_session_timeout 参数来终止空闲事务,比如:应用代码中忘记关闭已开启的事务,PGSQL会自动查杀这种类型的会话事务
MySQL
不支持终止空闲事务功能
30. 应付超大数据量
PGSQL
不能应付超大数据量,由于PGSQL本身的MVCC设计问题,需要垃圾回收,只能期待后面的大版本做优化
MySQL
不能应付超大数据量,MySQL自身架构的问题
31. 分布式演进
PGSQL
HTAP数据库:cockroachDB、腾讯Tbase
分片集群: Postgres-XC、Postgres-XL
MySQL
HTAP数据库:TiDB
分片集群: 各种各样的中间件,不一一列举
32. 数据库的文件名和命名规律
PGSQL
PGSQL在这方面做的比较不好,DBA不能在操作系统层面(停库状态下)看清楚数据库的文件名和命名规律,文件的数量,文件的大小
一旦操作系统发生文件丢失或硬盘损坏,非常不利于恢复,因为连名字都不知道
PGSQL表数据物理文件的命名/存放规律是: 在一个表空间下面,如果没有建表空间默认在默认表空间也就是base文件夹下,例如:/data/base/16454/3599
base:默认表空间pg_default所在的物理文件夹
16454:表所在数据库的oid
3599:就是表对象的oid,当然,一个表的大小超出1GB之后会再生成多个物理文件,还有表的fsm文件和vm文件,所以一个大表实际会有多个物理文件
由于PGSQL的数据文件布局内容太多,大家可以查阅相关资料
当然这也不能全怪PGSQL,作为一个DBA,时刻做好数据库备份和容灾才是正道,做介质恢复一般是万不得已的情况下才会做
MySQL
数据库名就是文件夹名,数据库文件夹下就是表数据文件,但是要注意表名和数据库名不能有特殊字符或使用中文名,每个表都有对应的frm文件和ibd文件,存储元数据和表/索引数据,清晰明了,做介质恢复或者表空间传输都很方便
33. 权限设计
PGSQL
PGSQL在权限设计这块是比较坑爹,抛开实例权限和表空间权限,PGSQL的权限层次有点像SQL Server,db=》schema=》object
要说权限,这里要说一下Oracle,用Oracle来类比
在ORACLE 12C之前,实例与数据库是一对一,也就是说一个实例只能有一个数据库,不像MySQL和SQL Server一个实例可以有多个数据库,并且可以随意跨库查询
而PGSQL不能跨库查询的原因也是这样,PGSQL允许建多个数据库,跟ORACLE类比就是有多个实例(之前说的实例与数据库是一对一)
一个数据库相当于一个实例,因为PGSQL允许有多个实例,所以PGSQL单实例不叫一个实例,叫集簇(cluster),集簇这个概念可以查阅PGSQL的相关资料
PGSQL里面一个实例/数据库下面的schema相当于数据库,所以这个schema的概念对应MySQL的database
注意点:正因为是一个数据库相当于一个实例,PGSQL允许有多个实例/数据库,所以数据库之间是互相逻辑隔离的,导致的问题是,不能一次对一个PGSQL集簇下面的所有数据库做操作
必须要逐个逐个数据库去操作,例如上面说到的安装pg_stat_statements插件,如果您需要在PGSQL集簇下面的所有数据库都做性能收集的话,需要逐个数据库去执行加载命令
又例如跨库查询需要dblink插件或fdw插件,两个数据库之间做查询相当于两个实例之间做查询,已经跨越了实例了,所以需要dblink插件或fdw插件,所以道理非常简单
权限操作也是一样逐个数据库去操作,还有一个就是PGSQL虽然像SQL Server的权限层次结构db=》schema=》object,但是实际会比SQL Server要复杂一些,还有就是新建的表还要另外授权
在PGSQL里面,角色和用户是一样的,对新手用户来说有时候会傻傻分不清,也不知道怎么去用角色,所以PGSQL在权限设计这一块确实比较坑爹
MySQL
使用mysql库下面的5个权限表去做权限映射,简单清晰,唯一问题是缺少权限角色
user表
db表
host表
tables_priv表
columns_priv表
1. 架构对比
Mysql:多线程
PostgreSql:多进程
多线程架构和多进程架构之间没有绝对的好坏,例如oracle在unix上是多进程架构,在windows上是多线程架构。
2. 对存储过程及事务的支持能力
MySql对于无事务的MyISAM表,采用表锁定,一个长时间运行的查询很可能会长时间的阻碍,而PostgreSQL不会尊在这种问题。
PostgreSQL支持存储过程,要比MySql好,具备本地缓存执行计划的能力。
3. 稳定性及性能
高并发读写,负载逼近极限下,PG的性能指标仍可以维持双曲线甚至对数曲线,到顶峰之后不再下降,而 MySql 明显出现一个波峰后下滑(5.5版本后Mysql企业版有优化,需要付费)
MySql的InnoDB引擎,可以充分优化利用系统的所有内存,超大内存下PG对内存使用的不那么充分(需要根据内存情况合理分配)。
4. 高可用
InnoDB的基于回滚实现的 MVCC 机制,对于 PG 新老数据一起放的基于 XID 的 MVCC机制,是占优的。新老数据一起存放,需要定时触发 VACUUM,会带来多余的 IO 和数据库对象加锁开销,引起数据库整理的并发能力下降。而且 VACUUM 清理不及时,还可能会引发数据膨胀
5. 数据同步方式:
Mysql到现在也是异步复制,pgsql可以做到同步、异步、半同步复制。
Mysql同步是基于binlog复制,属于逻辑复制,类似于oracle golden gate,是基于stream的复制,做到同步很困难,这种方式更加适合异步复制;
Pgsql的同是基于wal,属于物理复制,可以做到同步复制。同时,pgsql还提供stream复制。
Mysql的复制可以用多级从库,但是在9.2之前,PgSql不能用从库带从库。
Pgsql的主从复制属于物理复制,相对于Mysql基于binlog的逻辑复制,数据的一致性更加可靠,复制性能更高,对主机性能的影响也更小。
6. 权限控制对比
MySql允许自定义一套不同的数据级、表级和列的权限,运行指定基于主机的权限
Mysql的merge表提供了 一个独特管理多个表的方法。myisampack可以对只读表进行压缩,以后仍然可以直接访问该表中的行。
7. SQL语句支持能力
PG有极其强悍的 SQL 编程能力(9.x 图灵完备,支持递归!),有非常丰富的统计函数和统计语法支持,例如分析函数(Oracle的叫法,PG里叫window函数)
支持用多种语言来写存储过程,对于R的支持也很好。这一点上Mysql就差的很远,很多分析功能都不支持。
PgSql对表名大小写的处理,只有在Sql语句中,表明加双引号,才区分大小写。
在Sql的标准实现上要比Mysql完善,而且功能实现比较严谨。
对表连接支持比较完整,优化器的功能比较完整,支持的索引类型很多,复杂查询能力较强。
Mysql采用索引组织表,这种存储方式非常适合基于主键匹配的查询、删改操作,但是对表结果设计存在约束;
Mysql的Join操作的性能非常的差,只支持Nest Join,所以一旦数据量大,性能就非常的差。PostgresSQL除了支持 Nest Join 和 Sort Merge Join,PostgreSQL还支持正则表达式查询,MySql不支持。
8. 数据类型支持能力
PostgreSQL可以更方便的使用UDF(用户定义函数)进行扩展。
有丰富的几何类型,实际上不止集合类型,PG有大量的字典、数组、bitmap等数据类型,因此PG多年来在 GIS 领域处于优势地位。相比之下Mysql就差很多,instagram就是因为PG的空间数据扩展 PostGIS远远强于 MySql的 my spatial 而采用 PgSql的。Mysql中的空间数据类型有4种,分别是 CEOMETRY、POINT、LINESTRING、POLYGON,其空间索引只能在存储引擎为 MyiSam的表中创建,用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL。不同的存储亲情有差别。MyISAM和InnoDB 都支持 spatial extensions,但差别在于:如果使用MyISAM,可以建立 spatial index,而 InnoDB是不支持的。
pgsql对json支持比较好,还有很逆天的fdw功能,就是把别的数据库中的表当自己的用。
pgsql的字段类型支持的多,有很多mysql没有的类型,但是实际中有时候用到。
一半关系型数据库的字符串长度8k左右,无限长的 TEXT 类型的功能受限,只能作为外部带数据访问。而 PG 的 TEXT 类型可以直接访问,SQL 语法内置正则表达式,可以索引,还可以全文检索,或使用 xml xpath。用 PG 的话,文档数据库都可以省了。
postgresql 有函数,用于报表、统计很方便
PG支持 R-Trees这样可扩展的索引类型,可以方便的处理一些特殊数据。
PG可以使用函数和条件所以,使得数据库的调优非常灵活,mysql就没有这个功能,条件索引在web应用中很重要。
9. 如可过程容错能力
大批量数据入库,PostgreSql要求所有的数据必须完全满足要求,有一条错误,整个数据入库过程失败。MySql无此问题。
10. 表组织方式
pgsql用继承的方式实现分区表,让分区表的使用不方便且性能差,这点比不上mysql。
pg主表采用堆表存放,MySQL采用索引组织表,能够支持比MySql更大的数据量。
MySql分区表的实现要优于PG的基于继承表的分区实现,主要体现在分区个数达到成千上万后的处理性能差异很大。
11. 开发结构
对于web应用来所,mysql 5.6 的内置 MC API 功能很好用,PgSQL差一些。
PG的“无锁定”特性非常突出,甚至包括 vacuum 这样的整理数据空间的操作,这个和 PGSQL的 MVCC 实现有关系。
好文要顶 关注我 收藏该文
茄子777
粉丝 - 0 关注 - 0
+加关注
00
« 上一篇: 多线程中的wait与join
» 下一篇: 负载均衡相关
posted @ 2022-11-02 16:20 茄子777 阅读(55) 评论(0) 编辑 收藏 举报
刷新评论刷新页面返回顶部
登录后才能查看或发表评论,立即 登录 或者 逛逛 博客园首页
【推荐】阿里云新人特惠,爆款云服务器2核4G低至0.46元/天
【推荐】双十一同价!腾讯云云服务器抢先购,低至4.2元/月
编辑推荐:
· 一个有趣的 nginx HTTP 400 响应问题分析
· 谁说.NET没有GC调优?只改一行代码就让程序不再占用内存
· 为什么标准库的模板变量都是 inline 的
· .net 如何优雅的使用 EFCore
· 在 C# 中使用 Halcon 开发视觉检测程序
阅读排行:
· Entity Framework Core 7中高效地进行批量数据插入
· 除了 filter 还有什么置灰网站的方式?
· 快速绘制流程图“GitHub 热点速览 v.22.47”
· 使用.NET7和C#11打造最快的序列化程序-以MemoryPack为例
· 私藏!资深数据专家SQL效率优化技巧 ⛵
⑨ golang有没有好的开源游戏框架
1.为什么golang的开发效率高? golang是一编译型的强类型语言,它在开发上的高效率主要来自于后发优势,不用考虑旧有恶心的历史,又有一个较高的工程视角。
⑩ 01-Kubernetes 组件介绍
当你部署完 Kubernetes, 即拥有了一个完整的集群。
一个 Kubernetes 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。
工作节点托管作为应用负载的组件的 Pod 。控制平面管理集群中的工作节点和 Pod 。 为集群提供故障转移和高可用性,这些控制平面一般跨多主机运行,集群跨多个节点运行。
本节概述了交付正常运行的 Kubernetes 集贺蔽群所需的各种组件。
从上面的构架图可以看出来整个kubernetes集群分为control plane(master)和node节点两部份。master组件是集群的“脑力”输出者。它维护有kubernetesr 的所有对象记录,负责持续管理对象状态并响应集群中各种资源对象的管理操作,以及确保各资源对象的实际状态与所需状态相匹配。主要由API Server(kube-apiserver)、Control Manager(kube-controller-manager)和Scheler(kube-scheler)这3个组件。以及一个用于集群状态存储的etcd存储服务组成。
kube-apiserver
API Server是 Kubernetes控制平台的前端。支持不同类型应用的生命周期编排,包括部署、缩放和滚动更新等。还是整个集群的网关接口,由kube-apiserver守护程序运行为服务。通过HTTP/HTTPS协议将RESTful API公开给用户。是发往集群的所有REST操乎核作命令的接入点,并提供认证、授权、访问控制、API注册和发现等所有的REST请求。并将结果状态持久存储于集群状态存储系统(etcd)中。
kube-apiserver 支持同时提供 https(默认监听在 6443 端口)和 http API(默认监听在 127.0.0.1 的 8080 端口),其中 http API 是非安全接口,不做任何认证授权机制,不建议生产环境启用。两个接口提供的 REST API 格式相同
kube-controller-manager
Control Manager负责实现用户通过API Server提交的终态声明。它通过一系列操作步骤驱动API对象的当前状态逼近或同于期望状态。Kubernetes提供了驱动Node、Pod、Server、Endpoint、ServiceAccount和Token等数十种类型的API对象的控制器。从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它禅顷州们都被编译到同一个可执行文件,并在一个进程中运行。
控制器包括:
kube-scheler
Scheler是指为API Server 接收到的每一个pod创建请求,并在集群中为其匹配出一个最佳的工作节点为。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限等特性。
etcd
kubernetes集群的所有状态信息都需要持久存储于存储系统etcd中。etcd是由CoreOS基于Raft协议开发的分布式键值存储。可用于服务发现。共享配置以及一致性保障。生产环境中应该以etcd集群的方式运行以确保其服务可用性,并需要制周期备份策略以确保数据安全可靠。
etcd还为其存储的数据提供了监听(watch)机制。用于监视和推送变更,API Server是kubernetes集群中唯一能够与etcd通信的组件。封装了这种监听机制。并借此同其他各组件高效协同。
Node组件是集群中的“体力”输出者,因而一个集群通常会有多个Node以提供足够的承载力来运行容器化应用和其他工作负载。
kubelet
kubelet是运行于每个node节点之上的“节点代理”服务,负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理;其主要功能概括如下:
持续监听node的健康状态并向master汇报。
基于用户自定义的探针进行存活状态探测,并在任何Pod出现问题时将其重建为新实例。
准备pod所需的数据卷
返回pod的状态
在node节点执行容器的健康检测
Pod是一组容器组成的集合并包含这些容器的管理机制。安并未额外定义进程的边界或其他更多抽象,因此真正负责运行容器的依然是底层的容器运行时。kubelet通过CRI(容器运行时接口)可支持多种类型的OCI容器运行时,例如docker、 containerd、CRI-O、runC、fraki和kata Containers等
kube-proxy
kube-proxy也是需要运行于集群中每个节点之上的服务进程。它把API Server上的Service资源对象转换为当前节点上的iptables或与ipvs规则。这些规则能够将那些发往该Service对象ClusterIP的流量分发至它后端的Pod端点上。kube-proxy是kubernetes的核心网络组件。它本质上更象是Pod的代理及负载均衡器。负责确保集群中Node、Service和Pod对象之间的有效通信 。
kube-proxy 不同的版本可支持三种工作模式
UserSpace: kubernetes V1.1之前使用,V1.2及以后就已淘汰
IPtables: Kubernetes 1.1版本开始支持。1.2开始为默认
IPVS: kubernetes 1.9引入到1.11为正式版本,需要安装ipvadm、ipset工具包和加载ip_vs内核模块。
kubectl 概述
是一个通过命令行对kubernetes集群管理的工具
基于Web的用户接口,用于可视化k8s集群。dashborad可用于获取集群中资源对象的详细信息,Dashboard提供GUI,作为运维人员,使用kubectl命令行工具管理足矣
CoreDNS负责为整个集群提供DNS服务,它自1.11版本起默认使用CoreDNS,一种灵活,可扩展的DNS服务,之前的版本用到的是kube-dns项目,SkyDNS则是更早一代的解决方案。