Gerrit 是由 Google為了管理 android 項目而開發的,一款免費、開源的代碼審查軟件。Gerrit 使用 Git 作為底層版本控制系統,提供了代碼審查、權限管理等功能。
本文將會簡單介紹如何搭建分布式 Gerrit 集群,即搭建由一個可以讀寫的 Gerrit Master 和若幹個只讀的 Gerrit Slave 組成的 Gerrit 集群。Gerrit Slave 可以實時同步 Gerrit Master 的數據,保證代碼的一致性。
分布式的架構可以用來:
- 分流下載:下載代碼可以從只讀的 Slave 下載,從而減輕 Master 的負載。如果 Slave 和 Master 在不同地區,還可以起到加速下載的功效。
- 災備切換:如果 Master 出現故障,可以切換到 Slave 繼續工作。
分布式 Gerrit 架構
Gerrit 裏的數據主要是兩部分:
- Git 代碼庫,用來存儲代碼;
- 數據庫,用來存儲代碼提交(Change),用戶、分組權限等信息。
因此在實現分布式 Gerrit 時,對應兩部分數據,我們需要通過:
- PostgreSQL Streaming Replication
- Gerrit Replication 插件
來實現 Gerrit Master 和 Gerrit Slave 之間的數據同步。
分布式 Gerrit 架構如下圖所示。
+----------------------+ +--------------------+ | | | | | Gerrit Master | | Gerrit Slave | | Server | | Server | | +-----+-----+ | | | +----------+ | Gerrit | | +----------+ | | |Repository| |Replication| git push | |Repository| | | | +-+ Plugin +----------------->+ | | | +----------+ +-----+-----+ | +----------+ | | | | | | +--------------+ | | +--------------+ | | | PostgreSQL | | Replication | | PostgreSQL | | | | PRIMARY +------------------------>+ HOT-STANDBY | | | +--------------+ | | +--------------+ | +----------------------+ +--------------------+
在 Gerrit Master 和 Slave 上都有一個相同的 Git 代碼庫(*Repository*),Gerrit Replication 插件可以用來將 Master 上收到的更新(新提交的 commit, refs/meta
分支下的變更或是創建的新代碼庫)同步到 Slave。
為了實現數據庫的同步,需要將 PostgreSQL 運行在 Hot Standby 模式 。 在 Gerrit Master 上運行的 PostgreSQL 是 primary ,可以進行讀、寫操作; 在 Gerrit Slave 上運行的 PostgreSQL 是 stanby ,可以和 primary 保持同步,可以接受客戶端的連接,但只能進行讀操作。如果 primary 故障了,整個系統可以遷移( fail over )到 stanby ,由 stanby 承擔 primary 的角色。
分布式 Gerrit 配置
配置 Gerrit
對於安裝和配置 Gerrit Master,分布式的搭建和單點的搭建並沒有區別。
Gerrit Slave
安裝和配置 Gerrit Slave 上的 Gerrit 的時候,需要註意在 gerrit.config
文件裏的 [container]
下面添加 slave = true
。
[container] user = gerrit2 JavaHome = /usr/lib/jvm/java-7-Oracle/jre javaOptions = -Xmx80g -Xms20g -Xmn2g slave = true [database] type = postgresql database = reviewdb hostname = localhost username = gerrit2 ...
這樣 Gerrit 才會啟動為 Slave。
配置 PostgreSQL 數據庫
在 Master 上要配置 /etc/postgresql/9.4/main/postgresql.conf
,打開 Hot Standby 功能。
... wal_level = hot_standby ...
還需要在 /etc/postgresql/9.4/main/pg_hba.conf
添加 stanby
的 IP,確保 stanby
可以連接 primary
進行同步。
host replication all POSTGRES.STANDBY.IP.ADDRESS/32 md5
在 Slave 上首先需要配置 /etc/postgresql/9.4/main/postgresql.conf
,設置 PostgreSQL 運行為 stanby
。
... hot_standby = on ...
接下來,添加 /var/lib/postgresql/9.4/main/recovery.conf
文件,配置 primary
信息。
standby_mode = on primary_conninfo = 'host=POSTGRES.PRIMAY.IP.ADDRESS port=5432 user=replicator password=PASSWORD' trigger_file = '/var/lib/postgresql/postgresql.trigger'
其中 trigger_file
被用來觸發 fail over
,此時不需要創建。
配置完成後,在 primary 上運行命令將數據拷貝到 standby 。
rsync -av --exclude pg_xlog --exclude postgresql.conf data/* \ POSTGRES.STANDBY.IP.ADDRESS:/var/lib/postgresql/data/
重啟兩端的 PostgreSQL 後, primary 和 standby 將保持同步。
關於 Hot Standby 的詳細的說明,可以參見 Postgresql 的這篇 官方文檔 。
配置 Gerrit Replication
Gerrit Slave
首先需要在 Gerrit Slave 上配置 xinetd,用來提供 git daemon 服務。
$ sudo apt install xinetd $ cat /etc/xinetd.d/git-daemon # default: off # description: The git server offers access to git repositories service git service git { disable = no type = UNLISTED port = 9418 socket_type = stream wait = no env = HOME=/home/gerrit2 user = gerrit2 server = /usr/bin/git only_from = gerrit-master.example.com log_type = SYSLOG daemon info server_args = daemon --inetd --syslog --export-all --enable=upload-pack --enable=receive-pack --base-path=/home/gerrit2/review_site/git --verbose log_on_success += USERID HOST DURATION EXIT log_on_failure += USERID HOST ATTEMPT cps = 150 10 } $ sudo /etc/init.d/xinetd restart
重啟 xinetd 之後,9418 端口將會開啟,可以通過 git://
訪問 Gerrit Slave 上的代碼庫。
Gerrit Master
在 Gerrit Master 上,首先需要安裝 Gerrit Replication 插件,下載對應 Gerrit 版本的 Replication 插件 jar 文件,並添加到 $REVIEW_SITE/plugin
目錄下。
接下來,添加 $REVIEW_SITE/etc/replication.config
文件,加上 Gerrit Slave 的配置
[remote "slave"] url = git://gerrit-slave.example.com/${name}.git mirror = true threads = 4 adminUrl = ssh://gerrit-slave.example.com/home/gerrit2/review_site/git/${name}.git
註意, adminUrl
的路徑要按照 Gerrit Slave 上代碼庫真實的存放路徑設置。
這樣,啟動 Gerrit Master 之後,每次代碼庫有變更,Gerrit Replication 插件都會將變更通過 git 協議 Push 到 Slave 上。
通常,在啟動 Gerrit Slave 之前,需要將代碼庫拷貝到 Slave 機器上,以縮短首次同步的時間。
分布式 Gerrit 搭建完成之後,我們可以添加 .gitconfig
文件來實現代碼上傳和下載分流。
[url "ssh://<username>@gerrit-slave.example.com:29418"] insteadOf = gerrit pushInsteadOf = ssh://<username>@gerrit-master.example.com:29418
這樣,克隆代碼庫的時候使用命令
git clone gerrit:path/to/repo
可以從 Gerrit Slave 下載代碼,而 git push
的時候會自動將代碼 Push 到 Gerrit Master。
參考
- Setting Up Postgres Hot Standby
Tags: Gerrit 分布式 代碼 Master Slave 可以
文章來源: