10 วิธีลด Cost ในการใช้งาน Elasticsearch บน AWS
Tags: aws, awsthai, elasticsearch, opensearch
Published: 2021-09-01 16:24:24

## สารบัญ (Table of Contents)
[0. บทนำ](#intro)
[1. ลบข้อมูลที่ไม่จำเป็น](#prac1)
[2. จำแนกข้อมูลที่ไม่เกี่ยวข้องกัน แบ่งออกเป็นหลาย ๆ Index](#prac2)
[3. กำหนด Data Lifecycle Management Policy](#prac3)
[4. รวบรวม Elasticsearch หลาย ๆ cluster ในองค์กร ให้เหมาะสม](#prac4)
[5. Right Sizing Elasticsearch Servers](#prac5)
[6. ไม่ใช้ dedicated master nodes ถ้า cluster ไม่ได้สำคัญ หรือไม่ใหญ่พอ](#prac6)
[7. ซื้อ ​Reserved Instance (RI)](#prac7)
[8. ย้ายมาใช้ Amazon Elasticsearch Service เพื่อลด maintenance และ Data Transfer Inter-AZ Cost](#prac8)
[9. เปลี่ยน Instance Type เป็น Graviton เพื่อ price/performance ที่ดีกว่า](#prac9)
[10. ใช้พระเอก/นางเอก UltraWarm และ Cold Storage features บน Amazon Elasticsearch Service](#prac10)

<a name="intro"></a>
## บทนำ
Elasticsearch เป็น Search Engine NoSQL Database ที่มีการใช้งานเป็นวงกว้างและหลากหลาย ไม่ว่าจะเป็นการใช้งานการทำ Operational Logging, Log Analytics, การทำ Catalog Search หรือการทำ Index Table Searching ล้วนแล้วแต่เป็นการใช้งานที่จำเป็นต่อองค์กร และมักจะส่งผลให้เกิดค่าใช้จ่าย (cost) บน Elasticsearch cluster/servers ที่หลาย ๆ บริษัทอยากที่จะลดค่าใช้จ่ายในส่วนนี้ลง

สำหรับวิธีเบื้องต้นในการลดค่าใช้จ่ายที่อยากจะมาแนะนำผู้ใช้งาน Elasticsearch ทั้งในส่วนที่เป็น self-managed (ติดตั้ง Elasticsearch software เอง บน IaaS อย่าง Amazon EC2) หรือจะเป็น AWS managed service อย่าง [Amazon Elasticsearch Service](https://aws.amazon.com/elasticsearch-service/)

<a name="prac1"></a>
### 1. ลบข้อมูลที่ไม่จำเป็น
สำหรับข้อแรก ที่ดูเหมือนจะทำง่ายแต่จริง ๆ แล้วทำยาก แต่รู้ไหมว่านี่คือวิธีที่ได้ผลที่สุดในการลดค่าใช้จ่าย Elasticsearch เนื่องด้วย mindset ส่วนใหญ่เวลามีการใช้งาน Elasticsearch โดยเฉพาะ Logging use case แล้ว มักจะเกิดเหตุการณ์ **"เก็บ ๆ ไปก่อน ใช้ไม่ใช้ไม่รู้ แต่สักวันอาจจะได้ใช้"** ส่งผลให้เกิดค่าใช้จ่ายมหาศาลที่องค์กรต้องแบกรับ

วิธีแก้คือ ถ้าไม่ค่อยได้ใช้ (อาจจะดูจาก Search/Bulk metrics ของแต่ละ Index) ให้ปรับเปลี่ยน mindset ของผู้จัดเก็บ เช่นเอาเฉพาะ ERROR log level มาเท่านั้น หรืออีกวิธีง่าย ๆ คือเปลี่ยนไปเก็บที่ storage engine อื่นที่ถูกกว่า อย่างเช่น Amazon S3 แล้วถ้าจะใช้ ค่อย load กลับไปเมื่อต้องใช้ หรือใช้ Amazon Athena ดึงข้อมูลแทน

<a name="prac2"></a>
### 2. จำแนกข้อมูลที่ไม่เกี่ยวข้องกัน แบ่งออกเป็นหลาย ๆ Index
การทำการใด ๆ ก็ตามบน Elasticsearch มักจะอยู่ในรูปแบบของ Index (คล้าย ๆ Table ใน Relational Database) เช่นการเพิ่ม replica shard, ปรับ schema, หรือการลบข้อมูล เพราะฉะนั้นหากจำแนกข้อมูลที่ไม่เกี่ยวข้องกันให้อยู่ตามแต่ละ index ได้ จะส่งผลให้จัดการข้อมูล เช่นทำ compress, ย้ายไปยัง tier ต่าง ๆ, หรือลบ ได้อย่างสะดวกและเหมาะสม

การจำแนกข้อมูลนี้ สามารถทำได้ในระดับ insight ที่รู้เนื้อหา เช่นแยก Logging ในแต่ละ Level -> INFO, ERROR, TRACE, DEBUG ออกจากกัน หรือแบ่งส่วน application, security, server logging แยกจากกัน หรือจะแบ่งตามวันเวลา เช่น daily, monthly เป็นต้น

แต่ข้อควรระวังคือ ในแต่ละ Elasticsearch Cluster จะมี best practice index/shard sizing recommendation อยู่ ให้พยายาม design ให้อยู่ในกรอบนี้ (เกินได้นิดหน่อย) เพื่อให้ cluster stable[1]

<a name="prac3"></a>
### 3. กำหนด Data Lifecycle Management Policy
Elasticsearch ใน version ใหม่ ๆ จะมาพร้อมกับ feature Index Management[2] ที่จะช่วยให้ผู้ใช้งานสามารถกำหนด policy ของ index ได้ ว่าจะให้ทำการ merge, ลด replica, ย้าย tier, ปรับ priority, หรือลบข้อมูลได้

ต่อเนื่องจากข้อ 2 จะทำให้ผู้ใช้งานสามารถกำหนด policy ข้อมูล ตามการใช้งานจริงได้ เช่นข้อมูลที่สำคัญอย่าง security logging ให้ลบหลังจาก 2 ปี แต่ข้อมูลไม่สำคัญเช่น INFO logging อาจจะลบทุก ๆ 3 วัน เป็นต้น

แต่หากใครที่ใช้ version เก่าหน่อย ก็ลองดูตัว open-source เช่น [Curator](https://github.com/elastic/curator) ในการสร้าง policy ได้เช่นกัน

<a name="prac4"></a>
### 4. รวบรวม Elasticsearch หลาย ๆ cluster ในองค์กร ให้เหมาะสม
ในการใช้งาน Elasticsearch จริง ๆ แล้วผู้ใช้งานสามารถแบ่ง tenancy ของการเข้าถึงข้อมูลผ่าน Index และกำหนดสิทธิในการเข้าถึงข้อมูลผ่าน Authorization feature บน Fine-Gain Access Control ซึ่งแทนที่ผู้ใช้งานจะทำการสร้าง Elasticsearch cluster ขึ้นมาหลาย ๆ อัน (บางครั้งสร้างตาม application ด้วยซ้ำ) สามารถใช้งาน cluster เดียว ในรูปแบบของ share resource ได้ ซึ่งก็จะช่วยให้ผู้ใช้งาน utilize server resource ได้อย่างเต็มที่ และลดค่าใช้จ่ายในภาพรวมได้

<a name="prac5"></a>
### 5. Right Sizing Elasticsearch Servers
ในการใช้งาน Elasticsearch resource ก็จะมีความคล้ายกับ database ทั่ว ๆ ไป คือ เมื่อมีขนาดของข้อมูลเยอะขึ้น จำนวน resource (CPU, Memory, Disk) ที่ต้องการก็มากขึ้นตาม ทำให้บางครั้งเกิดการ over-provisioning บน Elasticsearch cluster ขึ้นมาได้ โดยหากผู้ใช้ทำการจัดการข้อมูล (ตามขั้นตอน 1,2,3,4) แล้วอาจจะพบว่า ข้อมูลมีขนาดลดลง ต่อมาก็จะเป็นการเปิดกว้างให้ผู้ใช้งานทำการปรับขนาดของ Elasticsearch server ให้เหมาะสม โดยอาจจะทำการลด size ของ server ให้เท่ากับที่ใช้งานในช่วง peak hour ได้

ซึ่งวิธีการปรับขนาดของ server ที่นิยมกันคือเพิ่ม (add) node ใหม่ที่มีขนาดเล็กกว่าเข้าไป แล้วค่อยถอด (remove) node ที่มีขนาดใหญ่กว่าออก เพื่อให้มี downtime น้อยที่สุดในการปรับเปลี่ยน server

ทาง AWS ก็มี guideline ให้กับผู้ใช้งานเบื้องต้นในการ sizing cluster ทั้งในส่วนของ Storage -> [Calculating storage requirements](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-storage) และ Instance -> [Choosing instance types and testing](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-instances)

<a name="prac6"></a>
### 6. ไม่ใช้ dedicated master nodes ถ้า cluster ไม่ได้สำคัญ หรือไม่ใหญ่พอ
การสร้าง Dedicated Master Node ถือเป็น Best Practice ใน production workload หรือ cluster ที่มีจำนวน shard และข้อมูลขนาดใหญ่ เพื่อ stability ของ cluster

แต่ไม่ใช่ทุก cluster จำเป็นที่จะต้องมี dedicated master node โดยทางผู้ใช้สามารถกำหนด node role ให้เป็นได้ทั้ง master และ data ได้ โดยตัว node นั้นจะทำงานทั้งสองงาน ซึ่งแน่นอนว่าก็จะใช้ resource มากกว่าปกติ และอาจจะไม่ stable เท่า แต่หากคิดถึงการใช้งาน non-production หรือ project ที่ไม่ได้ต้องการ 9'4 uptime ก็จะช่วยลดค่าใช้จ่ายได้อย่างมาก เพราะ dedicated master nodes ก็ต้องใช้อย่างน้อย ๆ 3 nodes ขึ้นไป ถึงจะเกิด stability ของ cluster

ตัว Amazon Elasticsearch Service ก็เปิดกว้างให้ผู้ใช้งานเลือกไม่มี dedicated master nodes ผ่าน "Custom" บน "Deployment Type" ด้วย

ในส่วนของการ sizing dedicated master node ทาง AWS ก็มี guideline ให้กับผู้ใช้งาน [Dedicated master nodes](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-managedomains-dedicatedmasternodes.html)

---
## เฉพาะ AWS หรือ Amazon Elasticsearch Service
![Amazon Elasticsearch Service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iaclzt1dw85xdtzevgr5.png)
วิธีการต่อไปนี้ สามารถทำได้บน AWS หรือ Amazon Elasticsearch Service ได้อย่างง่ายเนื่องจากตัว service มีการดูแลและจัดการให้อัตโนมัติ แต่อย่างไรก็ตาม ผู้ใช้งานสามารถนำ idea ไปปรับใช้กับ self-managed ได้เช่นกัน

<a name="prac7"></a>
### 7. ซื้อ ​Reserved Instance (RI)
วิธีนี้ใช้ได้กับทั้ง EC2 และ Amazon Elasticsearch Service โดยการซื้อ Reserved Instance จะเป็นการ commit จำนวนปีที่ต้องการใช้งาน แลกกับส่วนลดที่ทาง AWS มอบให้กับผู้ใช้งาน ยกตัวอย่างเช่นใน ap-southeast-1 region ใช้ data node r5.xlarge.elasticsearch จะมีค่ายใช้จ่าย on-demand $0.448/hr แต่หากซื้อ RI 1 year no-upfront จะมีค่ายใช้จ่าย $0.309/hr ซึ่งลดลงมาประมาณ 31% เลย โดยไม่ต้องแก้ไขหรือปรับแต่ง Infrastructure ใด ๆ

<a name="prac8"></a>
### 8. ย้ายมาใช้ Amazon Elasticsearch Service เพื่อลด maintenance และ Data Transfer Inter-AZ Cost
การย้ายจาก self-managed มายัง Amazon Elasticsearch Service นอกจากจะลดปัญหาเรื่องการดูแล Elasticsearch ด้วยตัวเองแล้ว ยังช่วยให้ผู้ใช้งานไป focus กับงาน implementation และ automation แทน รวมถึงยังช่วยลดค่า Data Transfer ระหว่าง Availability Zone ที่เกิดขึ้นภายใน Elasticsearch cluster ได้อีกด้วย

อ่านเพิ่มเติมเรื่องการคิดค่า Data Transfer บน Amazon Elasticsearch Service ได้จาก [Standard AWS data transfer charges](https://aws.amazon.com/elasticsearch-service/pricing/?nc=sn&loc=3#Standard_AWS_data_transfer_charges)

<a name="prac9"></a>
### 9. เปลี่ยน Instance Type เป็น Graviton เพื่อ price/performance ที่ดีกว่า
ตอนนี้ทาง AWS ได้มีการออก Instance Type แบบใหม่ที่นอกเหนือจาก Intel และ AMD ในชื่อ Graviton (m6g, r6g, c6g) ซึ่งจะมีค่าใช้จ่ายที่ถูกกว่าและมี performance ที่ดีขึ้น ในจำนวน CPU และ Memory ที่เท่าเดิม โดยตอนนี้ตัว Graviton ได้รองรับ Amazon Elasticsearch Service เรียบร้อยแล้ว โดยผู้ใช้งานสามารถเปลี่ยนมาใช้งาน Graviton Instance Type โดยไม่ต้องแก้ไข application หรือทำ data migration

ตัวอย่างเช่น หากเดิมมีการใช้งาน r5.2xlarge.elasticsearch (8 vCPU, 64GiB) ที่มีค่าใช้จ่าย On-Demand อยู่ที่ $0.897/hr แต่หากเปลี่ยนไปใช้งาน r6g.2xlarge.elasticsearch (8 vCPU, 64GiB เท่าเดิม) ที่มีค่าใช้จ่าย On-Demand อยู่ที่ $0.807/hr ซึ่งจะเห็นว่าถูกกว่าราว ๆ 10%

แต่มีข้อแม้ว่า จะต้องทำการ upgrade Amazon Elasticsearch Service ไปที่อย่างน้อย version 7.9 แล้วเท่านั้น[3]

<a name="prac10"></a>
### 10. ใช้พระเอก/นางเอก UltraWarm และ Cold Storage features บน Amazon Elasticsearch Service
หากพูดถึงการลด cost โดยเฉพาะ Logging หรือ Time-Series use cases การทำ Data Lifecycle Management (ข้อ 3) ถือเป็นจุดสำคัญที่ช่วยลด cost ขององค์กรอย่างมาก แต่หลาย ๆ ครั้งจะพบว่า การลบข้อมูลที่จำเป็นต้องใช้เร็วเกินไป อาจจะไม่ส่งผลดีนัก หรือผู้ใช้ไม่รู้ว่าข้อมูลนี้สามารถลบได้หรือไม่ ก็เกิดขาดความมั่นใจในการลบข้อมูล

ทาง Amazon Elasticsearch Service ได้มีการเพิ่ม feature Storage Tiering เข้ามาให้กับผู้ใช้งาน ซึ่งจะช่วยให้ผู้ใช้งานยังสามารถเก็บข้อมูล ค้นหาข้อมูล และสร้างกราฟจากข้อมูลบน data node และ storage ที่ถูกลง ผ่าน [UltraWarm Storage](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ultrawarm.html) โดยจะเป็นการย้ายข้อมูลส่วนที่เป็นข้อมูลเก่า, read-only ไปยังกลุ่ม nodes ที่มีราคาถูก โดยที่ยังสามารถ query หรือจัดการข้อมูลแบบเดิม, บน cluster เดิม, ไม่ต้องทำการแยก cluster ออกมาให้วุ่นวาย ซึ่งวิธีนี้จะช่วยให้ลดค่า cost ของ Elasticsearch cluster ได้อย่างมาก (สูงสุดราว ๆ 60-80% ขึ้นอยู่กับชนิดและขนาดของข้อมูล)

นอกจาก UltraWarm แล้ว ทาง Amazon Elasticsearch Service ยังได้เพิ่ม feature Storage Tiering ที่ถูกแบบพิเศษเข้ามา ในชื่อ [Cold Storage](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/cold-storage.html) ซึ่งจะช่วยให้ผู้ใช้งานเสียเงินเฉพาะค่า storage อย่างเดียว (ไม่เสียค่า compute เมื่อไม่ได้ใช้) แต่เมื่อใดก็ตามที่ผู้ใช้งานเรียกข้อมูลจาก Cold Storage ระบบจะค่อยคิดค่าใช้จ่ายตามเวลารันจริงที่เกิดขึ้นเท่านั้น

โดยทางผู้ใช้งานสามารถกำหนด policy ของการย้ายข้อมูลจาก Hot->UltraWarm->Cold ผ่าน [Index State Management](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html) เพื่อให้เกิดการทำแบบ automation ได้ทันที

แต่มีข้อแม้ว่า จะต้องทำการใช้ Amazon Elasticsearch Service ที่มี version อย่างน้อย 6.8 สำหรับ UltraWarm[4] และ version อย่างน้อย 7.9 สำหรับ Cold[5] โดยต้องมีการใช้ dedicated master nodes ใน cluster ด้วย

![CastleArm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctwjwej5if4j0jjmgkl3.jpg)

## แหล่งอ้างอิง
[1] https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-sharding
[2] https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html
[3] https://aws.amazon.com/about-aws/whats-new/2021/05/amazon-elasticsearch-service-offers-aws-graviton2-m6g-c6g-r6g-r6gd-instances/
[4] https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ultrawarm.html
[5] https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/cold-storage.html