成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用Spring對Postgres實現可擴展寫入

譯文
數據庫 PostgreSQL
本文著重介紹了我們公司如何應對基礎架構擴展方面的諸多挑戰之一:使用Spring和 Spring Data對Postgres數據庫實現可擴展寫入。

?譯者 | 布加迪

審校 | 孫淑娟

每個與客戶產生共鳴的技術型組織最終都會遇到擴展問題。擴展產品和組織對您的流程和基礎架構提出了新的要求。本文著重介紹了我們公司如何應對基礎架構擴展方面的諸多挑戰之一:使用Spring和Spring Data對Postgres數據庫實現可擴展寫入。

隨著用戶群越來越龐大,我們開始遇到一些性能問題,主要是受到我們的上游Postgres 數據庫的制約。我們的RPS(每秒請求)在短短幾個月內就從<50增加到了超過180,我們開始遇到SQL連接超時、連接斷開和延遲顯著增加等問題。這導致客戶體驗下降,這是不可接受的。

因此,我們著手研究如何消除這些Postgres瓶頸。我們很快意識到耗費太多的周期進行數據庫寫入,這阻塞了系統。對Postgres的每次寫入都是一次調用,這意味著如果我們想將50行保存到數據庫中,每行將調用1次,而不是執行一次SQL調用來保存所有這50行!

根本原因:在Hibernate中使用IDENTITY生成ID值

為什么我們無法進行批量更新?事實證明,問題與我們如何使用Hibernate為數據庫中的實體生成標識符值(即主鍵)有關。

我們使用的方法需要從IDENTITY列檢索值,新實體插入數據庫時??,Hibernate動態維護這些列。我們針對新資源寫入數據庫是在沒有指定id(主鍵)的情況下完成的,改而使用GenerationType.IDENTITY。

這是我們的Spring實體的樣子:

Kotlin
@Entity
@Table(name = "entity")
data class Entity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val metadata: String,
) : TenantEntity()

采用這種策略后,使用ORM來創建和更新現有資源顯得非常簡單:

  • 如果沒有傳遞id,會創建一個新行。
  • 如果傳遞了id,會更新現有行。

是不是聽起來很簡單?我們也是這么想的!而且似乎效果良好,直到后來我們意識到使用IDENTITY帶來了嚴重的性能問題。這種策略的缺點是批量更新不起作用。

這給我們帶來了一個大問題,因為我們的所有實體都使用IDENTITY標識符值生成。對于每個現有的表及對應的實體,我們必須將策略從IDENTITY換成支持批量插入語句的不同策略。

從IDENTITY遷移到基于序列的ID生成

我們研究可用于支持批處理的實體的其他生成類型后,遇到了Hibernate基于序列的標識符值生成。這個策略得到底層數據庫序列的支持。Hibernate從序列中請求下一個可用的id,為資源獲取新的id。

雖然該策略的底層機制超出了本文的討論范圍,但結論是,這種基于序列的策略將為我們實現批量插入。

現在我們需要弄清楚如何從現有的IDENTITY策略遷移到基于序列的新方法。

進一步調查后,我們意識到現有的表已經有一個Postgres序列。所以如果我們有一個這樣定義的表:

SQL
CREATE TABLE IF NOT EXISTS entity (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
...
)

將創建一個名為entity_id_seq的序列!

您可以運行以下SQL命令來檢查序列是否存在:

SELECT
*
FROM
pg_sequence
WHERE
seqrelid = 'entity_id_seq'::regclass;

由于我們能夠輕松訪問Postgres表的序列,因此可以進行非常本地化的更改,改而使用基于序列的策略來生成id。

對于每個實體,我們只需更改幾行代碼即可解決性能瓶頸。更新后的實體如下所示:

Kotlin
private const val TABLE = "entity"
private const val SEQUENCE = "${TABLE}_id_seq"
@Entity
@Table(name = TABLE)
data class Entity(
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE)
@SequenceGenerator(name = SEQUENCE, sequenceName = SEQUENCE, allocationSize = 50)
@Column(name = "id")
val id: Long? = null,
val metadata: String,
) : TenantEntity()

AllocationSize和序列增量大小

這里需要說明的一點是,Hibernate中的allocationSize屬性需要與Postgres中底層序列的增量大小相同。

這是為了讓Hibernate和底層序列在它們擁有的id方面“同步”。這還可以防止多臺服務器寫入到同一個表的分布式架構出現任何問題。

默認情況下,Postgres序列的增量大小為1。我們寫了一個非常快速的遷移來更改它,以便與我們的allocationSize匹配:

ALTER SEQUENCE entity_id_seq INCREMENT 50;

現在,Hibernate只需要進行1次調用,即可獲取每50次插入的id列表。

它也只需要1次調用即可插入這50行。

以下是我們從這個問題中得出的總結:

  • 如使用Hibernate,盡快開始使用基于數據庫序列的身份值生成,尤其是在您預見到寫入次數會增加的情況下。
  • 保持allocationSize和底層Postgres序列增量大小參數相同,避免id沖突,并支持分布式系統。

最后,這是我們實施該更改后RPS從近180變成約90的屏幕截圖。

原文標題:??Scalable Writes to Postgres With Spring??,作者:Aditya Bansal?

責任編輯:華軒 來源: 51CTO
相關推薦

2023-11-09 08:31:56

Spring微服務網關

2024-01-23 18:53:04

PostgreSQL關系數據庫

2023-12-12 07:30:54

IstioWasm前端

2025-02-10 10:54:53

PostgresDBpgvector數據庫

2021-05-17 07:28:23

Spring可擴展性項目

2020-02-12 09:00:48

數據網格Apache Igni數據管理

2015-04-23 13:29:02

Flume分布式服務HDFS

2009-03-16 09:16:13

行為擴展WCF.NET

2016-08-24 19:22:10

Docker SwarPython應用

2019-05-20 13:20:36

Python編程語言情感分析

2024-09-23 00:00:10

2013-06-25 21:08:33

Active PoweDatum環保

2025-05-06 08:09:02

2016-10-31 11:26:13

ReactRedux前端應用

2017-05-09 10:34:21

Spring BootDubbo Activ擴展

2017-04-28 08:32:40

Spring BootDubbo Activ使用

2024-02-01 08:28:28

2022-05-30 09:32:07

Spring容器

2025-05-28 02:55:00

PostgresOTelIceberg

2009-08-31 14:45:10

C#擴展方法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日日摸夜夜爽人人添av | 久久精品免费 | 国产在线拍偷自揄拍视频 | 久久精品视频网站 | 91精品久久久久久久久久 | 久草成人网 | 久久久婷| 中文字幕在线电影观看 | 国产黄色大片在线免费观看 | 精品国产高清一区二区三区 | 国产高潮好爽受不了了夜色 | 精品视频成人 | 在线播放亚洲 | 久久国产精品99久久久大便 | 欧美极品视频在线观看 | 人人人人干 | 一道本视频 | 国产在线高清 | 韩国成人在线视频 | 午夜一区二区三区视频 | 亚洲国产精品自拍 | 操久久久 | 久久噜噜噜精品国产亚洲综合 | 在线免费观看毛片 | 国产超碰人人爽人人做人人爱 | 亚洲欧洲一区二区 | 一级免费毛片 | 日韩精品av一区二区三区 | 国产精彩视频在线观看 | 亚洲欧美中文日韩在线v日本 | 精品毛片视频 | 99re在线视频精品 | 91玖玖| 天天操夜夜看 | 91亚洲精品国偷拍自产在线观看 | 精品一二三 | 在线免费观看黄色 | 亚洲欧美综合 | japanhdxxxx裸体| 精品在线观看一区 | 中文字幕乱码视频32 |