應用PMDK修改WAL操作使之適配持久化記憶體

yzs87 發表於 2019-08-11

應用 PMDK修改WAL操作使之適配持久化記憶體

這幾個補丁能夠通過使用 PMDK對儲存在持久化記憶體PMEM上的WAL日誌進行讀寫。PMEM是下一代儲存介質,具有一系列特性:快速、位元組定址、非易失。

Pgbench是PG的通用benchmark,使用benchmark進行測試,這些補丁修改後的PG比原生PG效能提升5%。使用我們的insert benchmark,能夠比原生PG快90%。下面進行詳細描述。

這個 e-mail包括以下幾部分:

A)PMDK

B)補丁

C)測試方法及結果

PMDK

PMDK提供函式使應用能夠直接訪問PMEM,無需通過核心作為記憶體。API包括:

1)open PMEM檔案的API、create PMEM檔案的API、map PMEM檔案到虛擬地址的API

    PMDK利用DAX檔案系統特性提供這些API函式。DAX檔案系統對PMEM敏感,允許直接訪問PMEM,而不使用核心的page cache。可以使用標準的mmap函式將DAX檔案系統中的檔案對映到記憶體。更進一步說,通過將PMEM中的檔案對映到虛擬地址,應用可以使用CPU的 load/store指令替代read/write訪問PMEM。

2)讀寫 PMEM檔案的API

PMDK提供API:類似memcpy()函式,通過single instruction、multiple data instruction、NT storage instruction 將資料拷貝到PMEM。這些指令能夠提升拷貝效能。因此這些API比read/write更快。API參考:

[1] http://pmem.io/pmdk/

[2]https://www.usenix.org/system/files/login/articles/login_summer17_07_rudoff.pdf

[3] SIMD: 對載入資料進行操作的單指令。如果SIMD系統一次載入8位元組資料到暫存器,那麼到PMEM的儲存操作會同時對所有8位元組值進行。

[4] NT store instructions: 該指令跳過CPU cache,因此使用該指令不需要flush。

補丁

補丁修改:

0001-Add-configure-option-for-PMDK.patch:新增--with-libpmem配置,通過pmdk庫執行IO

0002-Read-write-WAL-files-using-PMDK.patch:

使用 PMDK函式對WAL進行IO操作

wal_sync_method引數增加pmem-drain,用於標明PMEM上wal sync方式。

0003-Walreceiver-WAL-IO-using-PMDK.patch:

     對於備機的 walreciver程式,使用PMDK寫日誌。

執行方式及結果

    環境:

  Server: HP ProLiant DL360 Gen9

CPU:    Xeon E5-2667 v4 (3.20GHz); 2 processors(without HT)

DRAM:   DDR4-2400; 32 GiB/processor

        (8GiB/socket x 4 sockets/processor) x 2 processors

NVDIMM: DDR4-2133; 32 GiB/processor

        (8GiB/socket x 4 sockets/processor) x 2 processors

HDD:    Seagate Constellation2 2.5inch SATA 3.0. 6Gb/s 1TB 7200rpm x 1

OS:     Ubuntu 16.04, linux-4.12

DAX FS: ext4

NVML:   master(at)Aug 30, 2017

PostgreSQL: master

Note: I bound the postgres processes to one NUMA node, and the benchmarks to other NUMA node.

 

1)配置pmem,將之作為一個塊裝置

    # ndctl list

# ndctl create-namespace -f -e namespace0.0 --mode=memory -M dev

2)在pmem上建立一個檔案系統,以DAX方式掛載

    # mkfs.ext4 /dev/pmem0

# mount -t ext4 -o dax /dev/pmem0 /mnt/pmem0

3)設定PMEM_IS_PMEM_FORCE,表示WAL檔案存放在PMEM上

    注意,沒有設定這個環境變數, PG的程式啟動不起來

   # export PMEM_IS_PMEM_FORCE=1

4)安裝PG

    安裝 Pg時有3個重要注意事項:

a. Configure時新增--with-libpmem:"./configure --with-libpmem"

b. 將WAL目錄存放到PMEM上

c. 將wal_sync_method引數由fdatasync改為pmem_drain

    具體操作:

# cd /path/to/[PG_source dir]

# ./configure --with-libpmem

# make && make install

# initdb /path/to/PG_DATA -X /mnt/pmem0/path/to/[PG_WAL dir]

# cat /path/to/PG_DATA/postgresql.conf | sed -e s/#wal_sync_method\ =\

fsync/wal_sync_method\ =\ pmem_drain/ > /path/to/PG_DATA/postgresql.conf.

tmp

# mv /path/to/PG_DATA/postgresql.conf.tmp /path/to/PG_DATA/postgresql.conf

# pg_ctl start -D /path/to/PG_DATA

# created [DB_NAME]

5)執行2個benchmark,一個是pgbench,一個是my insert benchmark

  Pgbench:

      # numactl -N 1 pgbech -c 32 -j 8 -T 120 -M prepared [DB_NAME]

       執行 pgbench三次的平均值:

      wal_sync_method=fdatasync:   tps = 43,179

wal_sync_method=pmem_drain:  tps = 45,254

  pclinet_thread:my insert benchmark

       準備:

      CREATE TABLE [TABLE_NAME] (id int8, value text);

ALTER TABLE [TABLE_NAME] ALTER value SET STORAGE external;

PREPARE insert_sql (int8) AS INSERT INTO %s (id, value) values ($1, '

[1K_data]');

執行:

BEGIN; EXECUTE insert_sql(%lld); COMMIT;

Note: I ran this quer 5M times with 32 threads.

 

# ./pclient_thread

Invalid Arguments:

Usage: ./pclient_thread [The number of threads] [The number to insert

tuples] [data size(KB)]

# numactl -N 1 ./pclient_thread 32 5242880 1

 

測試三次的平均值:

wal_sync_method=fdatasync:   tps =  67,780

wal_sync_method=pmem_drain:  tps = 131,962

 

Attachment

Content-Type

Size

0001-Add-configure-option-for-PMDK.patch

application/octet-stream

5.1 KB

0002-Read-write-WAL-files-using-PMDK.patch

application/octet-stream

46.9 KB

0003-Walreceiver-WAL-IO-using-PMDK.patch

application/octet-stream

4.8 KB

 

  原文

https://www.postgresql.org/message-id/C20D38E97BCB33DAD59E3A1%40lab.ntt.co.jp


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2653324/,如需轉載,請註明出處,否則將追究法律責任。