ทำไมต้อง PostgreSQL? ลิงก์ไปยังหัวข้อ
สมมติว่าคุณได้ตัดสินใจใช้ PostgreSQL เป็นฐานข้อมูลของคุณแล้ว ทำไม? เพราะมันเป็นระบบฐานข้อมูล object-relational แบบโอเพนซอร์สที่ทรงพลัง มีการพัฒนาอย่างต่อเนื่องมากว่า 30 ปี ใช่ไหม? เราจะปล่อยปัญหาเรื่องที่เก็บและวิธีการเก็บข้อมูลไว้ก่อนในโอกาสหน้า
RDS Aurora (PostgreSQL Compatible) หรือ RDS PostgreSQL ลิงก์ไปยังหัวข้อ
ถ้าไม่มีข้อกำหนดเฉพาะเจาะจง เราอาจเลือก Aurora เป็นตัวเลือกเริ่มต้น ระบบจัดเก็บข้อมูลคือความแตกต่างหลักระหว่างสองตัวนี้ คุณไม่ต้องกังวลเรื่องพื้นที่เต็ม Aurora จะช่วยคุณเอง Aurora จะปรับขนาดพื้นที่จัดเก็บอัตโนมัติได้สูงสุดถึง 128 TB (พฤศจิกายน 2024) “ข้อมูลจะถูกทำสำเนาอัตโนมัติข้าม Availability Zones ข้อมูลของคุณจะมีความทนทานสูงและมีโอกาสสูญหายน้อย” คุณสามารถมี instance เดียวที่มีข้อมูลอยู่ใน 3 ที่ต่างกัน ถ้าคุณต้องการเพิ่มอีกหนึ่ง region มันจะทำให้เรามี 6 ที่ต่างกันทั่วโลกที่เก็บข้อมูล มหัศจรรย์ใช่ไหม?
พารามิเตอร์ของ PostgreSQL ลิงก์ไปยังหัวข้อ
มีพารามิเตอร์มากมายที่สามารถเปลี่ยนแปลงได้ แต่เราจะเน้นที่สำคัญและเป็นที่นิยมที่สุด โปรดสร้างกลุ่มพารามิเตอร์แบบกำหนดเองสองกลุ่มสำหรับ cluster และ instance ล่วงหน้า และอย่าใช้กลุ่มพารามิเตอร์เริ่มต้น เราไม่สามารถแก้ไขค่าพารามิเตอร์เริ่มต้นได้ และบางพารามิเตอร์ต้องรีบูต cluster/instance
log_min_duration_statement = 4000
- ระยะเวลาของคำสั่งในหน่วยมิลลิวินาทีที่เกินกว่านี้จะถูกบันทึก 0 จะบันทึกทุกคำสั่ง ค่าเริ่มต้นคือ -1 ปิดการบันทึก ข้อมูลเพิ่มเติมrds.force_ssl = 1
- บังคับใช้ SSL สำหรับการเชื่อมต่อทั้งหมด ค่าเริ่มต้นคือ 0 (ปิด) บังคับการเข้ารหัสระหว่างทาง ข้อมูลเพิ่มเติมlog_lock_waits = 1
- บันทึกการรอคอยล็อกนาน ค่าเริ่มต้นคือปิด ข้อมูลเพิ่มเติมmax_locks_per_transaction
- กำหนดจำนวนล็อกสูงสุดต่อธุรกรรม ค่าเริ่มต้นคือ 64 ข้อมูลเพิ่มเติมshared_preload_libraries = pg_stat_statements,pgaudit
- ระบุไลบรารีที่จะแชร์และโหลดล่วงหน้าเข้าไปในหน่วยความจำเซิร์ฟเวอร์ ค่าเริ่มต้นคือสตริงว่าง ข้อมูลเพิ่มเติม: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Extensions.htmlidle_in_transaction_session_timeout = 300000
- ยุติ session ที่มีธุรกรรมเปิดและไม่มีการใช้งานเกินเวลาที่กำหนดในหน่วยมิลลิวินาที ค่าเริ่มต้นคือ 0 (ปิด) ข้อมูลเพิ่มเติมlog_autovacuum_min_duration = 60000
- กำหนดเวลาการทำงานขั้นต่ำที่เกินกว่านี้การทำงาน autovacuum จะถูกบันทึก ค่าเริ่มต้นคือ -1 ปิดการบันทึก ข้อมูลเพิ่มเติม
การสร้างจากคอนโซล ลิงก์ไปยังหัวข้อ
สมมติว่าความต้องการเร่งด่วนและขาดเวลาและความรู้บังคับให้เราใช้คอนโซล จะเลือกอะไร คลิกตรงไหน?
- เลือกเทมเพลต production เสมอ กำหนด DB cluster identifier ซึ่งจะใช้ใน connection string ใช้ชื่อผู้ใช้ root ใดก็ได้ ตามค่าเริ่มต้นสำหรับ AWS Secrets Manager Integration ซึ่งจะเพิ่มการหมุนรหัสผ่าน root อัตโนมัติ
- ขนาดและพื้นที่จัดเก็บ ใช้ Aurora Standard และคลาส T ใดก็ได้เพื่อปรับงบประมาณให้เหมาะสม คุณสามารถเปลี่ยนแปลงได้ภายหลัง
- Serverless v2 ถ้าคุณใช้ไม่บ่อยและไม่รู้จักโหลด คุณสามารถใช้ serverless v2 ได้ มันจะปรับขนาดอัตโนมัติ จาก 0 ถึงสูงสุด แพงกว่ามากแต่ยืดหยุ่นมาก
- การเชื่อมต่อ ระวัง! อย่าใช้ default VPC ที่นี่ การคลิกสร้าง VPC แยกต่างหากใช้เวลาประมาณ 5-10 นาที และหลังจากสร้างฐานข้อมูลแล้วคุณไม่สามารถเปลี่ยน VPC ได้ เป็นจุดสำคัญ การย้ายฐานข้อมูล production อาจใช้เวลาหลายชั่วโมง เช่นเดียวกับการเข้าถึงแบบสาธารณะ หลีกเลี่ยง ใช้ VPNs, Direct Connect, Balancers และ RDS Proxy ใช้เวลาศึกษาว่ามีอะไรเข้าถึงฐานข้อมูลจากภายนอกบ้าง
- การเชื่อมต่ออีกครั้ง อย่าใช้ security group (ไฟร์วอลล์) เริ่มต้น สร้างอันใหม่ แม้ว่ากฎจะไม่ดีหรือผิดพลาด ก็ยังดีกว่ามี entity แยกที่ใช้เฉพาะกับฐานข้อมูลนี้
พารามิเตอร์ฐานข้อมูล เลือกกลุ่มพารามิเตอร์แบบกำหนดเองที่สร้างไว้ข้างต้น ไม่ใช่ค่าเริ่มต้น สามารถเปลี่ยนแปลงได้แต่ต้องรีบูต instance/cluster
การเข้ารหัสข้อมูลขณะพัก สร้าง KMS key แบบ multi-region แยกต่างหากเสมอ อย่างน้อยหนึ่ง Customer Managed KMS key จะช่วยได้มาก เราไม่สามารถเปลี่ยนพารามิเตอร์การเข้ารหัสหลังจากสร้างฐานข้อมูลแล้ว เช่นเดียวกับ performance insights
การสร้างจาก Terraform ลิงก์ไปยังหัวข้อ
เหมือนกับข้างต้น แต่เป็นโค้ด ไม่จำเป็นต้องอธิบายซ้ำ โค้ดนี้มีให้แล้ว https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/blob/master/examples/postgresql/main.tf
provider "aws" {
region = local.region
}
data "aws_availability_zones" "available" {}
locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Example = local.name
}
}
################################################################################
# RDS Aurora Module
################################################################################
module "aurora" {
source = "terraform-aws-modules/rds-aurora/aws"
version = "~> 9.0"
name = local.name
engine = "aurora-postgresql"
engine_version = "16.3"
master_username = "pgroot"
storage_encrypted = true
kms_key_id = module.kms.key_id
instances = {
1 = {
instance_class = "db.t4.medium"
}
}
vpc_id = module.vpc.vpc_id
db_subnet_group_name = module.vpc.database_subnet_group_name
security_group_rules = {
vpc_ingress = {
cidr_blocks = module.vpc.private_subnets_cidr_blocks
}
}
apply_immediately = true
engine_lifecycle_support = "open-source-rds-extended-support-disabled"
create_db_cluster_parameter_group = true
db_cluster_parameter_group_name = local.name
db_cluster_parameter_group_family = "aurora-postgresql16"
db_cluster_parameter_group_description = "${local.name} example cluster parameter group"
db_cluster_parameter_group_parameters = [
{
name = "log_min_duration_statement"
value = 4000
apply_method = "immediate"
}, {
name = "rds.force_ssl"
value = 1
apply_method = "immediate"
}, {
name = "log_lock_waits"
value = "1"
apply_method = "immediate"
}, {
name = "max_locks_per_transaction"
value = "1000"
apply_method = "pending-reboot"
}, {
name = "shared_preload_libraries"
value = "pg_stat_statements,pgaudit"
apply_method = "pending-reboot"
}, {
name = "idle_in_transaction_session_timeout"
value = "300000" # Max 5 minutes per transaction
apply_method = "immediate"
}, {
name = "log_autovacuum_min_duration"
value = "60000" # 1m, minimum execution time above which autovacuum actions will be logged
apply_method = "immediate"
}
]
create_db_parameter_group = true
db_parameter_group_name = local.name
db_parameter_group_family = "aurora-postgresql16"
db_parameter_group_description = "${local.name} example DB parameter group"
db_parameter_group_parameters = [
{
name = "log_min_duration_statement"
value = 4000
apply_method = "immediate"
}
]
enabled_cloudwatch_logs_exports = ["postgresql"]
create_cloudwatch_log_group = true
cloudwatch_log_group_tags = {
Sensitivity = "high"
}
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
tags = local.tags
}
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "~> 2.0"
deletion_window_in_days = 7
description = "KMS key for ${local.name} cluster activity stream."
enable_key_rotation = true
is_enabled = true
key_usage = "ENCRYPT_DECRYPT"
aliases = [local.name]
tags = local.tags
}
ต่อไป? ตัวเลือกอื่นๆ? ลิงก์ไปยังหัวข้อ
วันนี้เราครอบคลุม PostgreSQL บน RDS Aurora แล้ว แต่ยังมีตัวเลือกอื่นๆ อีกมากมาย ถูกที่สุดคือเก็บข้อมูลดิบเป็นวัตถุใน S3 ทนทานและมีการทำสำเนา แต่ช้าได้ Key-value stores อย่าง DynamoDB เร็ว แต่ไม่ใช่ฐานข้อมูลเชิงสัมพันธ์ สิ่งสำคัญที่สุดคือเริ่มจากปัญหาแล้วเลือกเครื่องมือที่เหมาะสมกับมัน