ROS Bundling
- Vertica file architecture
- New storage format
- How is the new format different?
- Does the new functionality bundle all projection files?
- Why is ROS bundling useful?
- What configuration parameters are associated with the bundling functionality?
- What is the upgrade impact from Vertica 7.1 to Vertica 7.2?
- Are the old and new formats compatible?
- 如何將數據從舊的存儲格式移動到新的格式?
- 如果我爲min_ros_filesize_kb指定的值與當前MaxBundleableROSSizeKB不同,該怎麼辦?
- 什麼時候是轉換爲新存儲格式的最佳時間?
- COMPACT_STORAGE()是否會影響查詢性能?
- COMPACT_STORAGE()需要運行多長時間?
- 我如何知道我的數據庫是否將從此功能中受益?
- 我可以使用哪個系統表查看捆綁的存儲容器?
- 如果我有大的存儲容器,是否可以使用100MB作爲min_ros_filesize_kb的值?
在Vertica 7.2之前,每列有兩個文件-數據文件和索引文件。從Vertica 7.2開始,此格式不再存在。現在,這兩個部分都存儲在一個文件中。此外,多個數據文件和索引文件也可以存儲在一個文件中。
Vertica file architecture
下圖說明了Vertica文件體系結構,以及如何將表和投影簡化爲文件:
New storage format
Vertica旨在處理大型數據集。磁盤上的文件大小從數百兆字節到數百千兆字節不等。Tuple Mover有助於管理數據存儲。內存中的緩衝區吸收trickle 流負載,並且當內存緩衝區已滿時,Tuple Mover mergeout 操作會將數據寫入ROS容器。爲了管理磁盤上的文件數,Tuple Mover mergeout 操作會合並大小相似的ROS容器以創建更大的容器。有關更多信息,請參見 Tuple Mover最佳實踐。
儘管此方法適用於大多數表,但它可能會在包含大量小文件的表上出現問題。如果您的數據集滿足以下任一條件,則可能會發生這種情況:
- 寬表包含NULL值列
- 分區範圍很小,例如按分鐘分區。不建議這樣做。
- 啓用了Local segmentation,並且將因子設置爲更高的數字。不建議這樣做。
這些因素會在磁盤上創建小文件,從而導致很多碎片,從而影響節點的恢復和備份操作。爲解決此問題,Vertica工程師開發了新的磁盤存儲格式和設計,從而減少了磁盤上存儲的文件數量。
How is the new format different?
現在,數據文件及其索引文件存儲在一個文件中。例如,在Vertica 7.2之前,一個具有兩列的投影,一個存儲容器存儲了六個文件。在Vertica 7.2和更高版本中,該容器存儲三個文件。如果這些文件小於1MB,則Vertica會將它們捆綁在一起,並將它們存儲爲一個文件。
Does the new functionality bundle all projection files?
不,捆綁僅發生在一個存儲容器內和一個存儲位置內。小於MaxBundleableROSSizeKB的列文件捆綁在一起;其他列文件則作爲獨立的列文件保存在存儲容器中。
Why is ROS bundling useful?
捆綁減少了存儲容器中文件的數量,從而減輕了對底層文件系統的壓力,並促進了更快的備份和還原操作以及恢復。捆綁不會減少目錄的大小,也不會消除ROS pushback error。Bundling 不會更改讀取列文件時使用的文件句柄數。
What configuration parameters are associated with the bundling functionality?
哪些配置參數與捆綁功能相關聯?
參數 | 數據類型/默認值 | 描述 |
---|---|---|
啓用存儲捆綁 | Boolean/True | 啓用或禁用存儲捆綁。 |
MaxBundleableROSSizeKB | Integer/1024 | 可以設置爲1024 KB。如果有多個數據文件低於此大小限制,則在同一容器和存儲位置中,文件將捆綁在一起。 |
CompactStorageJobSizeMB | Integer/ 2048 | 控制函數COMPACT_STORAGE()的作業大小。 |
What is the upgrade impact from Vertica 7.1 to Vertica 7.2?
從Vertica 7.1升級到Vertica 7.2有什麼影響?
升級不會自動將現有文件從舊格式轉換爲新格式。升級後,可以使用函數COMPACT_STORAGE()轉換現有文件的文件格式。如果EnableStorageBundling設置爲true,則將發生以下行爲:
- 所有新的裝入和插入均以新的存儲格式寫入。
- 合併後的現有存儲將以新的存儲格式寫入。
Are the old and new formats compatible?
新舊格式兼容嗎?
是。如果您升級數據庫,並且表中同時包含大文件和小文件,則可以有選擇地將小文件移至新格式,而將大文件保留爲舊格式。
如何將數據從舊的存儲格式移動到新的格式?
使用COMPACT_STORAGE(),如以下示例所示:
=> SELECT COMPACT_STORAGE(object-name,
object-name,
min-ros-filesize-kb,
small-or-all-files,
simulate);
該函數的示例輸出如下所示:
compact_storage
---------------------------------------------------------------------------------------------------------------
Task: compact_storage
On node node01:
Projection Name :public.foo_super | selected_storage_containers :2 | selected_files_to_compact :12 | files_after_compact : 2 | modified_storage_KB :0
On node node02:
Projection Name :public.foo_super | selected_storage_containers :2 | selected_files_to_compact :12 | files_after_compact : 2 | modified_storage_KB :0
On node node03:
Projection Name :public.foo_super | selected_storage_containers :2 | selected_files_to_compact :12 | files_after_compact : 2 | modified_storage_KB :0
Success
如果我爲min_ros_filesize_kb指定的值與當前MaxBundleableROSSizeKB不同,該怎麼辦?
COMPACT_STORAGE()函數參數min_ros_filesize_kb獨立於MaxBundleableROSSizeKB配置參數。該函數使用您爲min_ros_filesize_kb指定的值。這對MaxBundleableROSSizeKB的值沒有影響。如果要在新的合併和加載中捆綁較大文件,則必須更改MaxBundleableROSSizeKB的值。
什麼時候是轉換爲新存儲格式的最佳時間?
爲了獲得最佳結果,請在將Vertica數據庫升級到7.2之後,但在執行第一次備份之前,轉換現有文件。這有助於備份和還原,原因有兩個:
- 減少文件數量,從而加快備份速度。
- 傳輸新存儲,因此後續備份可以更快地運行。
您可以在運行compact_storage時使用數據庫。
COMPACT_STORAGE()是否會影響查詢性能?
COMPACT_STORAGE()在存儲容器級別讀取和寫入文件。與合併操作相比,它使用較少的內存,但會搶佔 磁盤I / O。
COMPACT_STORAGE()需要運行多長時間?
由於此功能會重寫文件,因此執行時間取決於更改的數據量。通過將COMPACT_STORAGE()函數參數Simulation設置爲TRUE來運行模擬,以確定將更改多少存儲空間。
您可以通過在表或投影級別上迭代運行COMPACT_STORAGE()來增量地重寫存儲格式。
我如何知道我的數據庫是否將從此功能中受益?
如果備份和還原操作很慢,則可能是因爲許多大文件沒有合併。您可以運行以下查詢來查找節點上投影的中位數文件大小:
=> SELECT MEDIAN(size) OVER() AS median_fsize
FROM vs_ros AS ros, storage_containers AS cont
WHERE ros.delid=cont.storage_oid
AND cont.node_name=‘node'
AND cont.projection_name=‘proj_name' limit 1;
You can also run COMPACT_STORAGE() in simulation mode to see how many files it can reduce:
=> SELECT COMPACT_STORAGE(‘table_or_proj_name’, 1024, ‘small’, ‘true’);
我可以使用哪個系統表查看捆綁的存儲容器?
查詢系統表VS_BUNDLED_ROS以查看捆綁了哪些列文件:
node_name| projection_id | sal_storage_id | ros_id | size_bytes | storage_id
---------+-------------------+--------------------------------------------------+-------------------+------------+-------------------
initiator| 45035996273721386 | 0262c017f1fb9eb26b8d8e6266a7005e00a0000000004041 | 45035996273721409 | 5 | 45035996273721409
initiator| 45035996273721386 | 0262c017f1fb9eb26b8d8e6266a7005e00a0000000004041 | 45035996273721413 | 5 | 45035996273721409
initiator| 45035996273721386 | 0262c017f1fb9eb26b8d8e6266a7005e00a0000000004041 | 45035996273721417 | 48 | 45035996273721409
(3 rows)
如果我有大的存儲容器,是否可以使用100MB作爲min_ros_filesize_kb的值?
要確定min_ros_filesize_kb的值,請在模擬模式下運行COMPACT_STORAGE()以確定資源使用情況。例如,如果您有一個包含100個數據文件的存儲容器,每個文件小於1MB,COMPACT_STORAGE()會將它們從200個文件更改爲1個文件。在這種情況下,將min_ros_filesize_kb的值指定爲100MB或1MB沒什麼區別。
如果您有另一個包含100個數據文件的容器,每個文件大約40MB,COMPACT_STORAGE()會將它們從200個文件更改爲1個文件。在這種情況下,指定100MB會產生積極的影響。如果我們指定1MB,則容器將從200個文件變爲100個文件。
要確定爲min_ros_filesize_kb設置什麼值,請按照以下步驟操作:
選擇一個投影。
確定文件數量和投影的中值文件大小。
在模擬模式下運行COMPACT_STORAGE(),其值的範圍從中位數到100MB。
根據模擬產生的值,確定數據庫的最佳位置。
以下示例顯示瞭如何分析compact_storage對更新的Vertica數據庫的需求和影響,以及如何確定min_ros_filesize_kb的最佳值:
檢查文件計數是否未捆綁:
=> SELECT COUNT(distinct (salstorageid))
* 2 /* one fdb and one pidx */
FROM v_internal.vs_ros
WHERE bundleindex < 0; -- older versions dont have bundleindex
count
---------
1379533
(1 row)
查找未捆綁的文件的大小和數量,按投影和節點分組:
=> SELECT CASE WHEN segment_lower_bound is not null THEN 'SEGMENTED' ELSE 'REPLICATED' END AS type,
schema_name,
projection_name,
max(used_bytes) max_used_bytes,
min(used_bytes) min_used_bytes,
CASE WHEN segment_lower_bound is not null THEN count (distinct colid) ELSE count (distinct colid), count(distinct rosid) AS nFiles
FROM storage_containers join v_internal.vs_ros ON (delid = storage_oid)
WHERE bundleindex < 0 -- older versions dont have bundleindex
GROUP BY 1,2,3 ,segment_lower_bound
ORDER BY 7 desc
;
type | schema_name | projection_name | max_used_bytes | min_used_bytes | nCols | nFiles
----------+-------------+-----------------+----------------+----------------+-------+--------
SEGMENTED | schema | clients_b1 | 92368520 | 14778 | 13 | 650
SEGMENTED | schema | clients_b0 | 47906279 | 14728 | 13 | 611
SEGMENTED | schema | clients_b0 | 100868741 | 18776 | 13 | 572
SEGMENTED | schema | clients_b0 | 59835832 | 15173 | 13 | 572
SEGMENTED | schema | clients_b1 | 58541167 | 15441 | 13 | 507
SEGMENTED | schema | clients_b1 | 61792636 | 14728 | 13 | 507
在不同的桶中分配文件大小以查看分佈情況`
=> SELECT
WIDTH_BUCKET (used_bytes, 0, 1024*1024*1024, 999) AS bucket, -- 1GB size of max bucket, 1000 buckets, (i.e. 1MB each bucket)
count(rosid) fileCnt
FROM
storage_containers JOIN v_internal.vs_ros ON (delid = storage_oid)
WHERE
schema_name = 'schema'
AND projection_name='clients_b1'
AND bundleindex < 0 -- older versions dont have bundleindex
GROUP BY 1
ORDER BY 1
;
bucket | fileCnt
-------+---------
1 | 715 <=== so many small 1 MB or less files
4 | 13
5 | 26
10 | 26
14 | 39
15 | 52
16 | 65
17 | 26
18 | 52
19 | 39
20 | 299
21 | 39
23 | 13
24 | 13
25 | 13
29 | 13
31 | 13
32 | 39
40 | 26
41 | 13
42 | 13
44 | 13
45 | 39
48 | 13
49 | 13
55 | 13
58 | 13
86 | 13
(28 rows)
在本例中,我們選擇5MB作爲壓縮存儲的大小。首先,進行預演,看看效果如何
=> SELECT COMPACT_STORAGE('schema.clients_b1', 5*1024, 'SMALL', true); -
compact_storage
----------------------------------------------------------------------------------------------------------------
Task: compact_storage
On node v_scrutinload_node0001:
Projection Name :schema.clients_b1 | selected_storage_containers :50 | selected_files_to_compact :1012 | files_after_compact : 50 | modified_storage_KB :35584
On node v_scrutinload_node0002:
Projection Name :schema.clients_b1 | selected_storage_containers :39 | selected_files_to_compact :730 | files_after_compact : 39 | modified_storage_KB :16566
On node v_scrutinload_node0003:
Projection Name :schema.clients_b1 | selected_storage_containers :39 | selected_files_to_compact :728 | files_after_compact : 39 | modified_storage_KB :23126
Success
執行COMPACT_STORAGE ()。這將使用IO和資源。通過投影執行此操作可以在執行時進行更多的控制:
=> SELECT COMPACT_STORAGE('schema.clients_b1', 5*1024, 'SMALL', false);
compact_storage
----------------------------------------------------------------------------------------------------------------
Task: compact_storage
On node v_scrutinload_node0001:
Projection Name :schema.clients_b1 | selected_storage_containers :50 | selected_files_to_compact :1212 | files_after_compact : 50 | modified_storage_KB :230564
On node v_scrutinload_node0002:
Projection Name :schema.clients_b1 | selected_storage_containers :39 | selected_files_to_compact :928 | files_after_compact : 39 | modified_storage_KB :221211
On node v_scrutinload_node0003:
Projection Name :schema.clients_b1 | selected_storage_containers :39 | selected_files_to_compact :926 | files_after_compact : 39 | modified_storage_KB :227449
Success
查看文件的新分發版
=> SELECT
WIDTH_BUCKET (used_bytes, 0, 1024*1024*1024, 999) AS bucket, -- 1GB size OF max bucket, 1000 buckets, (i.e. 1MB each bucket)
count(rosid) fileCnt
FROM
storage_containers JOIN v_internal.vs_ros ON (delid = storage_oid)
WHERE
schema_name = 'schema'
AND projection_name='clients_b1'
AND bundleindex < 0 -- older versions dont have bundleindex
GROUP BY 1
ORDER BY 1
;
bucket | fileCnt
-------+---------
14 | 1 <== small files are gone, largest one is 14MB ....
15 | 3
16 | 7
17 | 4
18 | 6
19 | 6
20 | 46
21 | 4
23 | 2
24 | 2
25 | 2
29 | 2
31 | 2
32 | 6
40 | 4
41 | 2
42 | 2
44 | 2
45 | 9
48 | 3
49 | 3
55 | 3
58 | 3
86 | 7
(24 rows)
比較buddy投影(b1)以查看影響
=> SELECT
CASE WHEN segment_lower_bound is not null THEN 'SEGMENTED' ELSE 'REPLICATED' END AS type,
schema_name,
projection_name,
max(used_bytes) max_used_bytes,
min(used_bytes) min_used_bytes,
CASE WHEN segment_lower_bound is not null THEN count (distinct colid) ELSE count (distinct colid) END as nCols,
count(distinct rosid) as nFiles
FROM storage_containers JOIN v_internal.vs_ros ON (delid = storage_oid)
WHERE bundleindex < 0 -- older versions dont have bundleindex
GROUP BY 1,2,3 ,segment_lower_bound
ORDER BY 7 desc;
type | schema_ | projection_| max_used_bytes | min_used_bytes | nCols | nFiles
----------+---------+------------+----------------+----------------+-------+--------
SEGMENTED | schema | clients_b0 | 47906279 | 14728 | 13 | 611
SEGMENTED | schema | clients_b0 | 100868741 | 18776 | 13 | 572
SEGMENTED | schema | clients_b0 | 59835832 | 15173 | 13 | 572
SEGMENTED | schema | clients_b1 | 61792636 | 16300430 | 3 | 44 <=== better !
SEGMENTED | schema | clients_b1 | 92368520 | 14086909 | 7 | 44
SEGMENTED | schema | clients_b1 | 58541167 | 15202738 | 3 | 43
(6 rows)