最近同时在参与云原生社区发起的基于《Kubernetes 源码剖析》一书为主要思路展开的 Kubernetes 源码研习社活动,同样每周一次作业,两次活动让我感受到了作业驱动的好处,给自己压力驱动自己向前走。研习社更是让我知道找到组织的重要性,看看其他人对同一个问题的看法,一起头脑风暴。
上下文就说到这,开始本文正题,高性能 TIDB 课程第一周的作业。
课程的整体计划如下:
TiDB 总体架构
对 TiDB 进行基准测试
通过工具寻找 TiDB 瓶颈
Execution 性能优化
DDL 性能优化
Planner 性能优化
事务层性能优化
下推计算的优化
TIDB 架构总览
本周主要讲述了 TIDB 生态圈、社区相关运营组成结构以及 tidb 的压测数据、TIKV 架构。其中 TICDC 对接消息队列是我感兴趣的一部分,后续有计划对 TICDC 的消息队列生态做出贡献,有兴趣的同学欢迎一起交流。
下面是官方的一个架构图:
学习了这一节课程可以对 TIDB 的全局情况有一个大体的了解,B站传送门
TIDB 的总体架构用一句话总结来说的话就是:PD 调度、TIDB 计算、TIKV 存储。
目前 TIKV 是 CNCF 孵化项目,目前正在走毕业投票流程,期待 TIKV 的毕业。
Homework
本次作业描述是这样的:本地下载 TIDB,TIKV,PD 源代码,改写源代码并编译部署以下环境:
1 TIDB
1 PD
3 TIKV
也就是需要部署一个最小集群,1 个 TIDB 节点,1 个 PD 节点,3 个 TIKV 节点,那就从编译源代码开始了解 TIDB 吧!
TIDB 编译部署
下载源代码并且编译
首先是下载源代码 git clone https://github.com/pingcap/tidb.git
首先官方 Repo 中没有提到如何去编译 TIDB,那就看看源代码库里面有什么内容。
下载后可以看到在源代码目录中有 Makefile 的编译文件,那自然是直接运行make命令先看看是否能够编译通过。
[root@normal11 tidb]# makeCGO_ENABLED=1 GO111MODULE=on go build -tags codes -ldflags '-X "github.com/pingcap/parser/mysql.TiDBReleaseVersion=v4.0.0-beta.2-948-g148f2d4-dirty" -X "github.com/pingcap/tidb/util/versioninfo.TiDBBuildTS=2020-08-16 06:24:53" -X "github.com/pingcap/tidb/util/versioninfo.TiDBGitHash=148f2d456bdc531bb212028f8499ece141e20401" -X "github.com/pingcap/tidb/util/versioninfo.TiDBGitBranch=master" -X "github.com/pingcap/tidb/util/versioninfo.TiDBEdition=Community" ' -o bin/tidb-server tidb-server/main.go
Build TiDB Server successfully!
复制代码
编译好了,在显示的编译内容中看到是编译到了bin目录下的tidb-server二进制文件,-o bin/tidb-server.
可以执行命令的 help 查看下都有什么参数可以设置:
[root@normal11 tidb]# ./bin/tidb-server -hUsage of ./bin/tidb-server: -L string log level: info, debug, warn, error, fatal (default "info") -P string tidb server port (default "4000") -V print version information and exit (default false)... -path string tidb storage path (default "/tmp/tidb") ... -store string registered store name, [tikv, mocktikv] (default "mocktikv") ...
复制代码
这里主要列了几个常用的,其中 store 提示默认会使用 mocktikv,其实目前默认是使用unistore,命令行的提示还没有更新,这几天会计划贡献,如果其他同学看到有兴趣的也可以尝试一下,代码就在main.go当中。
我们主要会用到path和store,在使用 tikv 进行存储时需要将store指定为tikv并且path参数配置为tikv的地址。
我这里的启动参数是这样的: ./bin/tidb-server -P 4001 -status 10081 -store tikv -path 192.168.1.11:3379
由于需要 TIKV 的地址,这个部署会在 TIKV 启动后再进行部署。
改代码使得在 TIDB 启动事务时,会打印一个"hello transaction"的日志
在看事务相关代码后发现事务的提交是在txn.go文件中的 Commit(ctx context.Context)方法,再继续往下看发现是调用到了2pc.go的 execute(ctx context.Context) 方法,所以我选择在这个方法的第一行打印了"hello transaction"。(本次作业)
func (c *twoPhaseCommitter) execute(ctx context.Context) (err error) { logutil.Logger(ctx).Info("hello transaction") ...
复制代码
PD 编译部署
下载源代码并且编译 git clone https://github.com/pingcap/pd.git
一样的,看到源码库中有 Makefile 文件,首先尝试下直接使用make进行编译。
编译的时候会发现一直卡在一个文件的下载中(如果网络科学上网应该没问题):
go mod tidy./scripts/embed-dashboard-ui.sh+ Clean up existing asset file+ Fetch TiDB Dashboard Go module - TiDB Dashboard directory: /root/gopath/pkg/mod/github.com/pingcap-incubator/tidb-dashboard@v0.0.0-20200807020752-01f0abe88e93+ Create asset cache directory+ Discover TiDB Dashboard release version - TiDB Dashboard release version: 2020.08.07.1+ Check embedded assets exists in cache - Cached archive does not exist - Download pre-built embedded assets from GitHub release - Download https://github.com/pingcap-incubator/tidb-dashboard/releases/download/v2020.08.07.1/embedded-assets-golang.zip % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 639 100 639 0 0 120 0 0:00:05 0:00:05 --:--:-- 149 1 8027k 1 101k 0 0 3976 0 0:34:27 0:00:26 0:34:01 11531
复制代码
可以看到这是在进行 dashboard 相关的工作,但是本次不需要 dashboard,所以看看是否能够跳过 dashboard。
在 Makefile 中直接搜索dashboard可以找到下面这两段:
ifeq ($(DASHBOARD), 0) BUILD_TAGS += without_dashboardelse BUILD_CGO_ENABLED := 1endif
...
ifneq ($(DASHBOARD), 0) # Note: LDFLAGS must be evaluated lazily for these scripts to work correctly LDFLAGS += -X "github.com/pingcap-incubator/tidb-dashboard/pkg/utils/version.InternalVersion=$(shell scripts/describe-dashboard.sh internal-version)" LDFLAGS += -X "github.com/pingcap-incubator/tidb-dashboard/pkg/utils/version.Standalone=No" LDFLAGS += -X "github.com/pingcap-incubator/tidb-dashboard/pkg/utils/version.PDVersion=$(shell git describe --tags --dirty)" LDFLAGS += -X "github.com/pingcap-incubator/tidb-dashboard/pkg/utils/version.BuildTime=$(shell date -u '+%Y-%m-%d %I:%M:%S')" LDFLAGS += -X "github.com/pingcap-incubator/tidb-dashboard/pkg/utils/version.BuildGitHash=$(shell scripts/describe-dashboard.sh git-hash)"endif
复制代码
看起来是DASHBOARD环境变量为 0 则不进行 dashboard 的编译工作,来尝试一下:
[root@normal11 pd]# DASHBOARD=0 make...go mod tidy./scripts/embed-dashboard-ui.sh+ Skip TiDB DashboardCGO_ENABLED=0 go build -gcflags '' -ldflags '-X "github.com/pingcap/pd/v4/server/versioninfo.PDReleaseVersion=v4.0.0-rc.2-134-g68d2ba6" -X "github.com/pingcap/pd/v4/server/versioninfo.PDBuildTS=2020-08-16 06:45:41" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitHash=68d2ba6b0e82f17231f5af8700b822a5f7eb4c98" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitBranch=master" -X "github.com/pingcap/pd/v4/server/versioninfo.PDEdition=Community"' -tags " swagger_server without_dashboard" -o bin/pd-server cmd/pd-server/main.goCGO_ENABLED=0 go build -gcflags '' -ldflags '-X "github.com/pingcap/pd/v4/server/versioninfo.PDReleaseVersion=v4.0.0-rc.2-134-g68d2ba6" -X "github.com/pingcap/pd/v4/server/versioninfo.PDBuildTS=2020-08-16 06:45:50" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitHash=68d2ba6b0e82f17231f5af8700b822a5f7eb4c98" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitBranch=master" -X "github.com/pingcap/pd/v4/server/versioninfo.PDEdition=Community"' -o bin/pd-ctl tools/pd-ctl/main.goCGO_ENABLED=0 go build -gcflags '' -ldflags '-X "github.com/pingcap/pd/v4/server/versioninfo.PDReleaseVersion=v4.0.0-rc.2-134-g68d2ba6" -X "github.com/pingcap/pd/v4/server/versioninfo.PDBuildTS=2020-08-16 06:45:54" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitHash=68d2ba6b0e82f17231f5af8700b822a5f7eb4c98" -X "github.com/pingcap/pd/v4/server/versioninfo.PDGitBranch=master" -X "github.com/pingcap/pd/v4/server/versioninfo.PDEdition=Community"' -o bin/pd-recover tools/pd-recover/main.go
复制代码
编译成功了,看看都编译了什么内容:
[root@normal11 pd]# ls binpd-ctl pd-recover pd-server
复制代码
可以看到有三个二进制文件,我们需要的是pd-server.
一样的 可以执行下 help 看看有什么参数,这里就不再演示了。
我这里使用的启动参数是:
./bin/pd-server -client-urls http://192.168.1.11:3379 -data-dir ./data
复制代码
TIKV 编译部署
TIKV 的编译算是最不容易搞定的部分了,主要是两部分:
Rust
git 子模块(网络慢)
由于之前有过 Rust 的 Hello World 经验,编译 Rust 对我来说问题不大,git 子模块慢还没有找到什么好办法,只能等待。
下载源代码并编译
和之前的一样,看到 Makefile 首先执行 make 看看有没有问题。
在编译的过程中回去拉取 git 子模块的代码,这部分很慢,我就不再演示了(不想再经历)。
[root@normal11 tikv]# make cargo build --release --no-default-features --features " jemalloc portable sse protobuf-codec" Compiling libc v0.2.66 Compiling cfg-if v0.1.10 Compiling log v0.4.8 ... Building [===========================================> ] 431/531: procfs, backtrace-sys(bui..
复制代码
最下面一行会提示当前编译的进度,你可以根据这个进度来计算自己可以喝几杯咖啡,这就是这个进度条的用处。
编译好后看看都有什么产物:
[root@normal11 tikv]# ls target/release/build deps examples incremental libcmd.d libcmd.rlib tikv-ctl tikv-ctl.d tikv-server tikv-server.d
复制代码
可以看到有tikv-ctl和tikv-server,我们部署需要的是tikv-server.
惯例,首先看一下 help 了解下都有什么参数可以设置。就不再演示了。 展示下我部署 3 个节点的 tikv 的启动参数:
target/debug/tikv-server --pd-endpoints http://192.168.1.11:3379 -A 192.168.1.11:20161 -f tikv.log --data-dir data
target/release/tikv-server --pd-endpoints http://192.168.1.11:3379 --status-addr 192.1.1.11:20152 -A 192.168.1.11:20162 -f tikv2.log --data-dir data2
target/release/tikv-server --pd-endpoints http://192.168.1.11:3379 --status-addr 192.8.1.11:20153 -A 192.168.1.11:20163 -f tikv3.log --data-dir data3
复制代码
由于我没有使用 dashboard,需要看 TIKV 集群的信息可以通过pd-ctl查看:
[root@normal11 tikv]# ../pd/bin/pd-ctl store -u http://192.168.1.11:3379 { "count": 3, "stores": [ { "store": { "id": 1, "address": "192.168.1.11:20161", "version": "4.1.0-alpha", "status_address": "127.0.0.1:20180", "git_hash": "df2fab45b19b5d067ff55ff5074819c50eef3ea2", "start_timestamp": 1597565907, "deploy_path": "/root/repo/tikv/target/release", "last_heartbeat": 1597567039153289831, "state_name": "Up" }, "status": { "capacity": "49.98GiB", "available": "10.43GiB", "used_size": "32.56MiB", "leader_count": 14, "leader_weight": 1, "leader_score": 14, "leader_size": 14, "region_count": 22, "region_weight": 1, "region_score": 979224935.3087239, "region_size": 22, "start_ts": "2020-08-16T16:18:27+08:00", "last_heartbeat_ts": "2020-08-16T16:37:19.153289831+08:00", "uptime": "18m52.153289831s" } }, { "store": { "id": 46, "address": "192.168.1.11:20163", "version": "4.1.0-alpha", "status_address": "192.168.1.11:20153", "git_hash": "df2fab45b19b5d067ff55ff5074819c50eef3ea2", "start_timestamp": 1597566768, "deploy_path": "/root/repo/tikv/target/release", "last_heartbeat": 1597567038217172506, "state_name": "Up" }, "status": { "capacity": "49.98GiB", "available": "10.43GiB", "used_size": "31.5MiB", "leader_count": 4, "leader_weight": 1, "leader_score": 4, "leader_size": 4, "region_count": 22, "region_weight": 1, "region_score": 979224925.9906679, "region_size": 22, "start_ts": "2020-08-16T16:32:48+08:00", "last_heartbeat_ts": "2020-08-16T16:37:18.217172506+08:00", "uptime": "4m30.217172506s" } }, { "store": { "id": 47, "address": "192.168.1.11:20162", "version": "4.1.0-alpha", "status_address": "192.168.1.11:20152", "git_hash": "df2fab45b19b5d067ff55ff5074819c50eef3ea2", "start_timestamp": 1597566769, "deploy_path": "/root/repo/tikv/target/release", "last_heartbeat": 1597567039620646027, "state_name": "Up" }, "status": { "capacity": "49.98GiB", "available": "10.3GiB", "used_size": "31.65MiB", "leader_count": 4, "leader_weight": 1, "leader_score": 4, "leader_size": 4, "region_count": 22, "region_weight": 1, "region_score": 1008811475.6201195, "region_size": 22, "start_ts": "2020-08-16T16:32:49+08:00", "last_heartbeat_ts": "2020-08-16T16:37:19.620646027+08:00", "uptime": "4m30.620646027s" } } ]}
复制代码
可以看到三个节点都是UP的状态,接下来开始测试一下事务的内容:
我创建了一个person的表,一个 name 字段和 money 字段.
插入一行数据查看事务的效果:
执行的语句如下:
begin;insert into person (name,money) values ('tidb',10);commit;
复制代码
会在执行 commit;的时候打印一句hello transaction.
[2020/08/16 16:48:57.336 +08:00] [INFO] [2pc.go:726] ["hello transaction"] [conn=2]
复制代码
以上就是本次作业的效果:
搭建一个最小的集群
修改源代码,在提交事务的时候打印一个hello transaction
其实这里打印的地方可能是不对的,这是在提交事务的时候才会打印,也就是执行commit;的时候,而作业内容是开始事务时也就是begin;时,不过我没有更多时间再看了,所以提交的作业就写在了execute时打印. :)
也算是给自己留个坑,等进一步熟悉 TIDB 后再回头来看看。
系列文章将会第一时间更新在 Github 的作业Repo中,有时间后再同步到这里。欢迎关注欢迎一起交流。
评论