Amazon DynamoDB
NoSQL key-value & document database
01ภาพรวม DynamoDB (NoSQL Overview)
Amazon DynamoDB เป็น fully managed, serverless, NoSQL database ที่ AWS ดูแลให้ทั้งหมด ไม่ต้องจัดการ server เอง สามารถ scale ได้ในระดับ massive (millions of requests per second, trillions of rows, 100s of TB storage) มี performance ระดับ single-digit millisecond latency ที่สม่ำเสมอ
DynamoDB เป็นแบบ key-value และ document model ข้อมูลถูก replicate ข้าม 3 Availability Zones (AZ) โดยอัตโนมัติ ทำให้มี high availability และ durability สูง รวมเข้ากับ IAM สำหรับ security/authorization/administration ได้ดี และมีต้นทุนต่ำพร้อม auto scaling
NoSQL vs SQL Database
- NoSQL databases ไม่รองรับ query joins (หรือรองรับจำกัด) และไม่มีการทำ aggregation แบบ SUM, AVG ฝั่ง database
- NoSQL databases scale แบบ horizontally (เพิ่ม node) ต่างจาก SQL ที่มักจะ scale แบบ vertical
- ข้อมูลทุกอย่างที่ query ควรอยู่ใน row/item เดียว (denormalized) เพราะไม่มี join
- DynamoDB เป็น NoSQL database (ไม่ใช่ relational) ต่างจาก RDS/Aurora ที่เป็น SQL
02Tables, Items, Attributes & Primary Keys
DynamoDB ประกอบด้วย Tables แต่ละ table มี Primary Key (ต้องกำหนดตอนสร้างและเปลี่ยนไม่ได้) แต่ละ table มี Items (เทียบเท่า rows) จำนวนไม่จำกัด และแต่ละ item มี Attributes (เทียบเท่า columns) ที่สามารถเพิ่มได้ตลอดเวลา และเป็น null ได้
ประเภทของ Primary Key
Data Types ที่รองรับ
- Scalar Types: String, Number, Binary, Boolean, Null
- Document Types: List, Map (รองรับ nested JSON)
- Set Types: String Set, Number Set, Binary Set
03Read/Write Capacity Modes
DynamoDB มี 2 capacity modes ในการควบคุมว่าจะจัดการ read/write capacity อย่างไร และเลือกได้ว่าจะใช้แบบไหน และสามารถ switch mode ได้ทุก 24 ชั่วโมง
| ประเด็น | Provisioned | On-Demand |
|---|---|---|
| การวางแผน capacity | ต้อง provision RCU/WCU | ไม่ต้องวางแผน |
| Auto Scaling | รองรับ (min/max + target utilization) | scale อัตโนมัติเต็มที่ |
| หน่วย | RCU / WCU | RRU / WRU |
| ราคา | ถูกกว่าเมื่อ load สม่ำเสมอ | แพงกว่า แต่จ่ายตามใช้จริง |
| เหมาะกับ | predictable traffic | unpredictable/spiky traffic, workload ใหม่ |
04การคำนวณ RCU & WCU (สำคัญมาก)
Write Capacity Units (WCU)
- 1 WCU = 1 write per second สำหรับ item ขนาด สูงสุด 1 KB
- ถ้า item ใหญ่กว่า 1 KB ต้องใช้ WCU มากขึ้น โดย ปัดเศษขึ้น (round up) ไปที่ 1 KB ที่ใกล้ที่สุด
- สูตร: WCU = (จำนวน writes/วินาที) x ceil(item size / 1 KB)
ตัวอย่าง WCU: เขียน 10 items/วินาที ขนาด item 2 KB -> 10 x ceil(2/1) = 10 x 2 = 20 WCU. เขียน 6 items/วินาที ขนาด 4.5 KB -> 6 x ceil(4.5/1) = 6 x 5 = 30 WCU
Read Capacity Units (RCU)
- 1 RCU = 1 Strongly Consistent Read/วินาที สำหรับ item ขนาดสูงสุด 4 KB
- 1 RCU = 2 Eventually Consistent Reads/วินาที สำหรับ item ขนาดสูงสุด 4 KB
- Read size ปัดเศษขึ้น ไปที่ 4 KB ที่ใกล้ที่สุด
- Eventually Consistent Read (default): อาจอ่านข้อมูลเก่า (stale) ได้ถ้าอ่านทันทีหลัง write แต่ throughput ดีกว่า 2 เท่า
- Strongly Consistent Read: อ่านได้ข้อมูลล่าสุดเสมอ ใช้ RCU มากกว่า 2 เท่า และ latency สูงกว่า เปิดด้วย parameter ConsistentRead = true ใน GetItem/Query/Scan
ตัวอย่าง RCU (Strongly Consistent): อ่าน 10 reads/วินาที ขนาด item 4 KB -> 10 x ceil(4/4) = 10 RCU. ขนาด item 6 KB -> ceil(6/4) = 2 -> 10 x 2 = 20 RCU
ตัวอย่าง RCU (Eventually Consistent): อ่าน 16 reads/วินาที ขนาด item 12 KB -> ceil(12/4) = 3 RCU ต่อ strongly read แต่ eventual ได้ 2 reads ต่อ RCU -> (16/2) x 3 = 8 x 3 = 24 RCU
05Secondary Indexes: LSI vs GSI
โดย default เรา query ได้เฉพาะตาม primary key (partition + sort) เท่านั้น ถ้าต้องการ query/sort ตาม attribute อื่น ต้องสร้าง Secondary Index มี 2 แบบคือ LSI และ GSI
| ประเด็น | LSI | GSI |
|---|---|---|
| Partition Key | เหมือน base table | ใหม่ได้ (เปลี่ยน partition key) |
| Sort Key | alternative sort key | optional sort key ใหม่ |
| สร้างเมื่อไหร่ | ตอน create table เท่านั้น | ได้ทุกเมื่อ (add/remove ภายหลังได้) |
| จำนวนสูงสุด | 5 LSI ต่อ table | 20 GSI ต่อ table (default soft limit) |
| Throughput | ใช้ร่วมกับ base table | มี RCU/WCU แยกของตัวเอง |
| Consistency | รองรับ strongly consistent ได้ | Eventually consistent เท่านั้น |
06Query vs Scan (PartiQL)
Query Operation
- Query ดึง items ตาม partition key value (ต้องระบุ =) และ optional sort key condition (=, <, <=, >, >=, between, begins_with)
- FilterExpression: filter ฝั่ง client side เฉพาะ non-key attributes (ไม่ลด RCU ที่ใช้ เพราะ filter หลังอ่านแล้ว)
- Query มีประสิทธิภาพดีกว่า Scan มาก เพราะอ่านเฉพาะ partition ที่เกี่ยวข้อง
- Query ได้สูงสุด 1 MB ของข้อมูลต่อครั้ง ใช้ pagination เพื่ออ่านต่อ
Scan Operation
- Scan อ่าน ทั้ง table แล้วค่อย filter ออก -> ใช้ RCU เยอะ ช้า ไม่มีประสิทธิภาพ
- อ่านได้สูงสุด 1 MB ต่อครั้ง ต้องใช้ pagination ต่อ
- เพิ่มความเร็วด้วย Parallel Scan (หลาย worker scan พร้อมกัน) แต่จะใช้ RCU มากขึ้น
- ใช้ ProjectionExpression เพื่อเลือกเฉพาะ attribute ที่ต้องการ (ลดข้อมูลที่ส่งกลับ) และ FilterExpression เพื่อ filter ฝั่ง client
ProjectionExpression = ระบุ attribute ที่จะ return กลับมา (เหมือน SELECT columns). FilterExpression = กรอง item หลังอ่าน (ใช้ได้กับ non-key attribute, ไม่ช่วยประหยัด RCU). Pagination = เมื่อผลลัพธ์เกิน 1 MB จะมี LastEvaluatedKey ให้ส่งต่อใน ExclusiveStartKey ครั้งถัดไป
PartiQL เป็น SQL-compatible query language สำหรับ DynamoDB รองรับ SELECT, INSERT, UPDATE, DELETE ผ่าน syntax คล้าย SQL (แต่ยังไม่มี JOIN) ใช้ได้ทั้งใน console, CLI, API
07Conditional Writes, Optimistic Locking & Atomic Counters
DynamoDB รองรับการเขียนแบบมีเงื่อนไขเพื่อป้องกัน race condition และ data corruption โดยใช้ ConditionExpression
Conditional Writes
- ใช้ ConditionExpression ใน PutItem/UpdateItem/DeleteItem/BatchWriteItem ให้เขียนเฉพาะเมื่อเงื่อนไขเป็นจริง
- ฟังก์ชันที่ใช้ได้: attribute_exists, attribute_not_exists, attribute_type, contains, begins_with, size
- ถ้าเงื่อนไขไม่ผ่านจะได้ ConditionalCheckFailedException และไม่เสีย write capacity เต็ม
Optimistic Locking (Version Attribute)
Optimistic Locking ใช้ version number attribute เพื่อให้แน่ใจว่า item ไม่ถูกแก้โดยคนอื่นก่อนที่เราจะ update/delete. แต่ละ write จะตรวจว่า version ตรงกับที่อ่านมาหรือไม่ (ใช้ ConditionExpression เทียบ version) ถ้าตรงจึงเขียนและเพิ่ม version ขึ้น 1 ถ้าไม่ตรงแสดงว่ามีคนแก้ไปแล้ว -> เขียนล้มเหลว
Atomic Counters
Atomic Counter ใช้ UpdateItem กับ UpdateExpression แบบ ADD (เช่น SET attr = attr + :val) เพื่อเพิ่ม/ลดค่า number attribute แบบ atomic โดยไม่ต้องอ่านก่อน เหมาะกับ use case เช่น นับจำนวน website visits, view count ทำงานได้แม้มี concurrent updates
# Conditional write: เขียนเฉพาะเมื่อ item ยังไม่มี (ป้องกันการเขียนทับ)
aws dynamodb put-item \
--table-name Users \
--item '{"UserId": {"S": "u123"}, "Name": {"S": "Alice"}}' \
--condition-expression "attribute_not_exists(UserId)"
# Atomic counter: เพิ่ม view count ขึ้น 1 แบบ atomic
aws dynamodb update-item \
--table-name Pages \
--key '{"PageId": {"S": "home"}}' \
--update-expression "SET ViewCount = ViewCount + :inc" \
--expression-attribute-values '{":inc": {"N": "1"}}'08TTL & DynamoDB Streams
Time To Live (TTL)
- TTL ลบ item โดยอัตโนมัติหลังจากเวลาที่กำหนด (expiry timestamp ใน Unix epoch seconds)
- การลบเกิดขึ้นภายในประมาณ 48 ชั่วโมง หลังหมดอายุ (ไม่ใช่ทันที)
- TTL ไม่ใช้ WCU (ไม่มีค่าใช้จ่าย capacity ในการลบ)
- Item ที่ถูก TTL ลบ จะถูกลบจาก LSI/GSI ด้วย และส่ง event เข้า DynamoDB Streams (REMOVE)
- Use case: reduce stored data, session data, regulatory/compliance, expire ข้อมูลเก่า
DynamoDB Streams
DynamoDB Streams เป็น ordered stream ของ item-level modifications (create/update/delete) ใน table ใช้สำหรับ react ต่อการเปลี่ยนแปลงแบบ real-time ข้อมูลใน stream เก็บไว้ 24 ชั่วโมง
- ใช้ร่วมกับ Lambda triggers (Event Source Mapping) เพื่อประมวลผลเมื่อข้อมูลเปลี่ยน
- หรืออ่านผ่าน Kinesis Client Library (KCL) applications
- Use cases: ส่ง notification, สร้าง analytics, replicate ข้าม region, อัปเดต ElasticSearch/OpenSearch, derived tables
StreamViewType (ข้อมูลที่ส่งใน stream)
- KEYS_ONLY: เฉพาะ key attributes ของ item ที่เปลี่ยน
- NEW_IMAGE: item ทั้งตัวหลังการเปลี่ยนแปลง
- OLD_IMAGE: item ทั้งตัวก่อนการเปลี่ยนแปลง
- NEW_AND_OLD_IMAGES: ทั้งก่อนและหลัง
09DynamoDB Accelerator (DAX)
DAX (DynamoDB Accelerator) เป็น fully managed, in-memory cache สำหรับ DynamoDB โดยเฉพาะ ช่วยลด latency จาก milliseconds เหลือ microseconds สำหรับ cached reads แบบ seamless (ไม่ต้องแก้ application logic — ใช้ DAX API ที่ compatible กับ DynamoDB API)
- แก้ปัญหา hot key (อ่าน item เดิมซ้ำ ๆ จำนวนมาก) ได้ดี
- TTL ของ cache default 5 นาที (300 วินาที) ปรับได้
- DAX มี 2 caches: Item Cache (สำหรับ GetItem/BatchGetItem) และ Query Cache (สำหรับ Query/Scan)
- Cluster มีได้สูงสุด 10 nodes ต่อ cluster, แนะนำ multi-AZ (อย่างน้อย 3 nodes ใน production)
- Secured ด้วย encryption at rest (KMS), VPC, IAM, CloudTrail
| ประเด็น | DAX | ElastiCache |
|---|---|---|
| ออกแบบมาเพื่อ | DynamoDB โดยเฉพาะ | cache ทั่วไป (Redis/Memcached) |
| การแก้ application | ไม่ต้องแก้ logic (compatible API) | ต้องเขียน cache logic เอง |
| เหมาะกับ | cache individual objects / query-scan results | store aggregation results / cross-table results |
10DynamoDB Transactions
DynamoDB Transactions ให้ความสามารถ ACID (Atomicity, Consistency, Isolation, Durability) ข้ามหลาย items และหลาย tables แบบ all-or-nothing — ทุก operation สำเร็จทั้งหมด หรือ fail ทั้งหมด
- มี 2 modes: Read Transactions (TransactGetItems) และ Write Transactions (TransactWriteItems)
- เป็น strongly consistent reads สำหรับ transactional reads
- ใช้ capacity 2 เท่า: transactional write ใช้ 2 WCU ต่อ item (1 KB), transactional read ใช้ 2 RCU ต่อ item (4 KB) เพราะต้อง prepare + commit
- รองรับสูงสุด 100 items หรือ 4 MB ของข้อมูลต่อ transaction
- Use cases: financial transactions, ระบบจองที่ต้อง consistency, multiplayer games
11Throttling, Backoff & Large Items Pattern
Throttling & ProvisionedThroughputExceededException
ถ้า exceed provisioned RCU/WCU จะได้ ProvisionedThroughputExceededException สาเหตุที่พบบ่อย: hot keys (partition key ถูกอ่านบ่อยเกินไป), hot partitions, หรือ item ใหญ่เกินไป
วิธีแก้ Throttling
- Exponential Backoff เมื่อเจอ exception (SDK ทำ retry แบบ exponential backoff ให้อัตโนมัติ)
- ออกแบบ partition key ให้กระจายดี (high cardinality) เพื่อเลี่ยง hot partition
- ถ้า RCU เป็นปัญหาเพราะอ่าน item เดิมซ้ำ ๆ -> ใช้ DAX
- เปิด DynamoDB Auto Scaling หรือเปลี่ยนเป็น On-Demand mode
Large Items Pattern (เก็บข้อมูลใหญ่)
เนื่องจาก item สูงสุด 400 KB ถ้าต้องเก็บข้อมูลใหญ่กว่านี้ (เช่น รูปภาพ, ไฟล์, blob) ให้ใช้ pattern: เก็บ object จริงใน Amazon S3 แล้วเก็บเฉพาะ metadata + reference (S3 object key/URL) ใน DynamoDB
- เก็บไฟล์ใหญ่ใน S3, เก็บ pointer/metadata ใน DynamoDB
- สำหรับ attribute ขนาดใหญ่ที่อยากเก็บใน DynamoDB เอง อาจ compress ข้อมูล (GZIP) ก่อนเก็บเป็น Binary
- Pattern นี้ช่วยลดขนาด item, ลด RCU/WCU, และหลบ 400 KB limit
คำถามทบทวน
ทดสอบความเข้าใจหัวข้อ Amazon DynamoDB
23 ข้อ · เลือกคำตอบเพื่อดูเฉลยและคำอธิบาย
1.แอปพลิเคชันต้องการเก็บไฟล์รูปภาพขนาด 5 MB พร้อม metadata ของผู้ใช้ใน DynamoDB วิธีออกแบบที่ดีที่สุดคือข้อใด?
2.Table ต้องการ Strongly Consistent Reads 10 ครั้งต่อวินาที โดย item แต่ละตัวมีขนาด 6 KB ต้อง provision RCU เท่าใด?
3.นักพัฒนาต้องการเพิ่มจำนวน view count ของหน้าเว็บแบบ atomic เมื่อมี request หลายตัวพร้อมกัน ควรใช้วิธีใด?
4.แอปมี traffic ที่ไม่สามารถคาดเดาได้และมี spike แบบสุ่ม ไม่ต้องการจัดการ capacity ควรเลือก capacity mode ใด?
5.นักพัฒนาต้องการ query items โดยใช้ partition key เดิม แต่ต้องการ sort key ที่แตกต่างจาก base table และ table ยังไม่ได้สร้าง ควรใช้อะไร?
6.เมื่อเขียนข้อมูลผ่าน GSI ถูก throttle แต่ WCU ของ main table ยังเหลือ จะเกิดอะไรขึ้น?
7.ต้องการ trigger Lambda function ทุกครั้งที่มี item ใหม่ถูกเพิ่มเข้า DynamoDB table เพื่อส่ง welcome email ควรทำอย่างไร?
8.แอปอ่าน item เดิมซ้ำ ๆ จำนวนมาก (hot key) ทำให้ latency สูงและเปลือง RCU ต้องการลด latency เหลือ microseconds โดยแก้โค้ดน้อยที่สุด ควรใช้อะไร?
9.ระบบโอนเงินต้องการให้การหักเงินจากบัญชี A และเพิ่มเงินให้บัญชี B สำเร็จพร้อมกันทั้งคู่ หรือ fail ทั้งคู่ ควรใช้คุณสมบัติใดของ DynamoDB?
10.Transactional write 5 items ต่อวินาที โดยแต่ละ item ขนาด 1 KB ต้องใช้ WCU เท่าใด?
11.นักพัฒนาพบว่า query ทำงานช้าและเปลือง RCU มากเพราะอ่านข้อมูลทั้ง table แล้วค่อยกรอง สาเหตุและวิธีแก้ที่ดีที่สุดคือ?
12.ต้องการให้ session data ถูกลบอัตโนมัติเมื่อหมดอายุโดยไม่ต้องเขียน job ลบเอง และไม่ต้องการเสีย WCU ควรใช้อะไร?
13.เกี่ยวกับ TTL ใน DynamoDB ข้อใดถูกต้องที่สุด?
14.นักพัฒนาต้องการป้องกันไม่ให้สอง process update item เดียวกันทับกันจนเกิด lost update ควรใช้เทคนิคใด?
15.เมื่อ application เจอ ProvisionedThroughputExceededException ควรทำอย่างไรเป็นแนวทางที่ AWS แนะนำ?
16.ต้องการเลือกเฉพาะบาง attribute ที่จะส่งกลับมาในผลลัพธ์ Query เพื่อลดข้อมูลที่ส่ง ควรใช้ parameter ใด?
17.ข้อใดอธิบาย Eventually Consistent Read ใน DynamoDB ได้ถูกต้อง?
18.ขนาดสูงสุดของ item เดียวใน DynamoDB คือเท่าใด?
19.นักพัฒนาต้องการ query DynamoDB ด้วย syntax คล้าย SQL (SELECT/INSERT/UPDATE/DELETE) ควรใช้อะไร?
20.Provisioned table ต้องเขียน 8 items ต่อวินาที โดยแต่ละ item ขนาด 3.5 KB ต้อง provision WCU เท่าใด?
21.ข้อใดคือความแตกต่างหลักระหว่าง DAX และ ElastiCache เมื่อใช้กับ DynamoDB?
22.DynamoDB Streams เก็บข้อมูล records ไว้นานเท่าใด และ StreamViewType ใดที่ให้ทั้งภาพก่อนและหลังการเปลี่ยนแปลง?
23.เมื่อต้องการ migrate จาก provisioned mode ไป on-demand mode ข้อจำกัดที่ต้องทราบคือข้อใด?