0153 | ความเชื่อผิดๆ ใน config apache ที่เจอบ่อย

เจอบ่อยๆ มาก็ค่อนข้างหงุดหงิดพอควร เรื่องการตั้งค่า “อะไรบางอย่าง” ของ apache ครับ… เวลาไปจูนเครื่องชาวบ้านแล้วเจออะไรแบบนี้ก็จะปวดหัวพอควร

ความจริงมี MySQL ด้วย แต่เขียนไปเขียนมา apache ก็ยาวแล้ว แยกไปเป็นครั้งหน้า (ที่ไม่รู้ว่าจะมาเมื่อไหร่) แล้วกัน 555+

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      2000
MaxClients       2000
MaxRequestsPerChild  4000
</IfModule>

ตัวอื่นไม่ซีเรียส แต่ตัวที่มีปัญหาคือ ServerLimit กับ MaxClients ครับ สองค่านี้ส่วนมากจะไปคู่กันครับ เพราะ ServerLimit คือค่าสูงสุดที่อนุญาตให้ MaxClients ตั้งได้… (แล้วทำไมมึงต้องแยก! อ่าน docs แล้วยังไม่เข้าใจ) แต่เอาเป็นว่าสองค่านี้ควรจะเท่ากันเสมอครับ ด้านล่างเป็นคำอธิบายจากเว็บของ apache เอง

Special care must be taken when using this directive. If ServerLimit is set to a value much higher than necessary, extra, unused shared memory will be allocated. If both ServerLimit and MaxClients are set to values higher than the system can handle, Apache may not start or the system may become unstable.

With the prefork MPM, use this directive only if you need to set MaxClients higher than 256 (default). Do not set the value of this directive any higher than what you might want to set MaxClients to.

ด้วยความที่หลายคนคงเข้าใจไปว่า ค่าสองตัวนี้คือจำนวน uip หรือจำนวน user online บนหน้าเว็บ หรืออะไรก็มิอาจทราบได้ ทำให้ตั้งค่านี้สูงเกินจริง กะว่าเว็บจะรับคนเข้าได้เยอะๆ แต่หารู้ไม่… คุณเข้าใจผิดครับ

เอาล่ะ ทีนี้ถ้าเซตไอ้บ้านี่ไว้เยอะๆ จะเกิดอะไรขึ้น ขออธิบายเป็นข้อๆ ตามนี้ละกันครับ

  • Apache ปกติ จะใช้วิธีแตก process ย่อย 1 process ต่อ 1 connection
  • รูปแบบการทำงานปกติของเว็บคือ request then response and close คือ เมื่อ client ส่งคำร้องไปแล้ว server ควรจะตอบกลับไปให้เร็วที่สุด แล้วก็ตัดการเชื่อมต่อทันทีที่ส่งข้อมูลเสร็จ
  • หมายความว่า ณ เวลาเดียวกัน (simultaneously) ควรจะมี connection ค้างอยู่บน Apache ไม่เยอะ (ถ้าไม่มีการปล่อยให้ download ไฟล์ใหญ่ๆ)
  • ทีนี้ 1 process ของ apache (ที่มี PHP อยู่ด้วย) เนี่ย มันจะกินแรมประมาณ 20 MB เป็นอย่างน้อย แต่ค่าเฉลี่ยที่เจอจริงๆ คือ 40-50 MB
  • เนื่องจาก เราถือว่า apache ควรจะประมวลผลและตอบกลับไปได้เร็วที่สุด สมมติ 1 request ใช้เวลาตอบกลับได้ภายใน 0.2 วินาที เท่ากับว่า 1 process ของ apache สามารถรับ request ได้ วินาทีละ 5 request หมายความว่า ถ้าตั้งไว้ 100 process ก็สามารถรองรับได้ถึง 500 request ต่อวินาที !!
  • ทีนี้ ถ้าตั้งค่านี้สูงมากๆ กรณีที่เกิดมี script ค้างขึ้นมา… แล้วทำให้ apache มี connection (หรือ process) ค้างเป็นจำนวนมาก ปริมาณแรมที่ apache ใช้ก็จะพุ่งพรวดๆ จนเกินกว่าที่เครื่อง server มีให้ ก็จะไปกิน swap แล้วก็ตายอนาถ ล่มทั้งเครื่องในที่สุด แม้แต่ remote ก็ทำไม่ได้
  • การตั้งค่านี้ไว้ให้พอดี / ใกล้เคียงกับปริมาณแรมที่มี โดยเอาค่าเฉลี่ยการใช้แรมต่อ 1 process มาหารปริมาณแรมที่มี (เช่น มีแรม 8000 MB หารด้วยค่า process ละ 50 MB จะได้ค่าที่เหมาะสมคือราวๆ 160 ) จะช่วยลดผลกระทบเวลา server ทำงานหนักได้ดีมาก เพราะเมื่อ connection เต็ม apache ก็ยังกินแรมไม่หมด หรืออาจเกินมานิดหน่อย ทำให้ process อื่นยังทำงานได้ โดยเฉพาะ remote ทำให้เข้าไปแก้ไขปัญหาได้
  • การตั้งค่า maxclients ไว้สูง จึงไม่ได้หมายความว่า server จะรองรับการใช้งานได้เยอะขึ้นแต่อย่างใด … เอวัง

Tags: ,

0152 | Full site CDN for upic.me

อดีตเมื่อปี 2010 : หลังจากเป็น reverse proxy ธรรมดาๆ มาได้พักนึง ตอนนี้ก็ขยายระบบเป็น full site cdn เรียบร้อยแล้วฮับ :) พร้อมกับเพิ่ม node ขึ้นมาหลายประเทศเลย

ก่อนทำ response time เฉลี่ย 1.55 วินาที

หลังทำ response time เฉลี่ยลดลงมาเหลือแค่ 0.56 วินาที !! (ลดลง 0.99 วินาที)

จริงๆ ระบบหลักที่เคยเขียนไว้ก็สามารถทำ read/write splitting ได้แล้ว แถมทำ async write สำหรับการ update สถิติและข้อมูลการเข้าดูไว้แล้วด้วย แต่ปัญหาใหญ่สุดคือ maintain code ยากขึ้น ต้องทำ versioning กับ code environment detection ใหม่ให้ดีๆ อีกที แล้วก็มีบางส่วนจำเป็นต้องเป็น synchronous writing ก็เลยต้องพึ่ง proxy กลับไปให้ทำงานที่ node เดียวเพื่อไม่ให้มีปัญหาอีกที (comment / up รูปก็อืดเหมือนเดิมไปละกัน)

รายการ node ตอนนี้ แผนที่คร่าวๆ ได้แบบนี้ครับ Node หลักอยู่ที่ไทย เส้นม่วงเป็น Cache ธรรมดา ส่วนเส้นชมพูเป็น Full CDN ยิงรอบสามประเทศคือ TH,US,DE แบ่งโครงข่ายได้ตามคำอธิบายด้านล่างฮะ

  • 3x Thailand รับผิดชอบ traffic ภายในประเทศไทยทั้งหมด
  • 2x TH-Inter เนื่องด้วยมันมี capacity ต่ำแต่ bandwidth inter สูง ก็ให้มันรับภาระส่งต่อข้อมูลไปให้ node ต่างประเทศ + รับการใช้งานแถวๆ SEA นิดหน่อย
  • 1x Singapore รองรับการใช้งานย่าน SEA และ Australia รวมถึงเป็นเส้นทางหลักสำหรับส่งต่อข้อมูลให้ US
  • 2x Hong Kong รองรับการใช้งานจากจีน ญี่ปุ่น เกาหลี เอเชียใต้ รวมถึงเป็นเส้นทางหลักสำหรับส่งต่อข้อมูลให้ DE และเส้นทางรองสำหรับ US
  • 1x US (Missouri) รองรับการใช้งานทวีปอเมริกาทั้งหมด (ทั้งเหนือกลางใต้) รับภาระจาก googlebot / facebook / msnbot ด้วย แล้วก็เป็น Full CDN Node คือ script เว็บทำงานที่ตัวเอง ดึงฐานข้อมูลจากตัวเองเลย ไม่ต้องส่งคำร้องมาไทย
  • 1x Germany รองรับการใช้งานทั้งยุโรป เอเชียตะวันตก รัสเซีย และแอฟริกา แถมเป็น Full CDN ด้วย แต่ยัง sync ข้อมูลไม่เสร็จ ตอนนี้ส่งต่อไปให้ US ชั่วคราว (แต่ก็เร็วกว่าส่งกลับมาไทยเยอะ)