Server อาการแบบนี้ คิดว่าเป็นที่อะไรครับ

load average มันสูง ไม่ทราบว่าเกิดจากอะไร ตรง database ก็ทำ index แล้ว




  1. ขอดู query เต็มๆหน่อย
  2. ทำ index field ไหนไปบ้างครับ

ป.ล. ตันที่ I/O

query มีหลายอันอ่ะครับ เอาอันไหน

หนักสุดน่าจะอันนี้เรียกข้อมูลกระทู้ (จะเรียกจาก database เมื่อมีการเปลี่ยนแปลง ถ้าไม่เปลี่ยนจะดึงจาก textfile ที่ cache ไว้)
select * from post where Topic_ID = 123456 order by Topic_Update limit 0,20
ทำ index ที่ Topic_ID ตารางอื่นๆก็ทำ index field ที่ต้อง where อ่ะครับ ซึ่งส่วนใหญ่จะเป็น ID

ทำระบบ cache แล้ว ทำการซอยตารางที่มีข้อมูลเยอะๆเป็นตารางย่อยๆแล้ว
ตารางที่มีข้อมูลเยอะสุดคือตาราง post แต่ซอยเป็นย่อยๆแล้ว

มันเป็นไปได้หรือเปล่าว่า HDD พัง

ได้ทำ index ที่ topic_update ด้วยมั้ยครับ พวก order by ต้องทำด้วยนะครับ

อ๋า… ไม่ได้ทำตรงพวก order by เลยครับ ไม่ทราบมาก่อนว่าต้องทำตรงนี้ด้วย เดี๋ยวจะไล่เช็คใหม่หมด ขอบคุณมากครับ

ปล. แต่ผมยังคิดว่าไม่น่าเป็นที่ mysql นะ เพราะหลายครั้งที่ load ขึ้นสูงทั้งที่แทบไม่มีการ query

key efficiency ต่ำฮะ 97.2% เอง ลอง check index ดีๆ (เปิด log queries not using indexes แล้วดูจากในนั้น)

feedback หน่อยนะครับว่าดีขึ้นแค่ไหน คือผมมั่นใจว่ามันดีขึ้นแน่ๆล่ะ แต่ก็คงยังมีอีกหลายจุดต้องมาไล่กันน่ะครับ

wa% สูงมากครับ
I/O ตัน

ลองเปลี่ยน select key1,key2,key3… from post ดูครับ

cat /etc/my.cnf มาดูหน่อยครับ

อีกเรื่องนึง แรม 4GB นี่ ตั้ง MaxClients ของ apache ไว้ซัก 80-100 อันก็พอครับไม่งั้นได้เตะลง swap แล้วช้านรกแน่ๆ

ตอนนี้กำลังแก้ไข ได้ผลยังไงพรุ่งนี้จะมาบอกความคืบหน้าครับ


ในไฟล์ my.cnf มีแค่นี้ครับ

[mysqld]
local-infile=0
max_connections=400
query_cache_size=320M
log-queries-not-using-indexes

ตอนแรกมีแค่
[mysqld]
local-infile=0

3 บรรทัดหลังผมเพิ่งใส่เข้าไปวันนี้เอง


ขอถามเรื่องทำ index หน่อยครับ ถ้าข้อมูลใน field นั้น มันมีค่าแค่ไม่กี่แบบ ควรจะทำ index หรือเปล่าครับ
เช่น เว็บบอร์ดแบ่งเป็น 3 ห้อง ดังนั้นใน field Topic_Group มีแค่ข้อมูลได้แค่ 3 แบบเป็นชื่อของห้อง คือ cartoon, game, movie อะไรทำนองนี้ หรือ field ที่มีข้อมูลได้แค่ 0 กับ 1
ลักษณะแบบนี้ เหมาะแก่การทำ index หรือเปล่าครับ


และก็เรื่อง log queries not using indexes ผมไปหาข้อมูลมาพอทราบแล้วว่าให้เอาไปใส่ในไฟล์ my.cnf แต่ไม่ทราบว่าแล้วจะไปดูที่ตรงไหนครับ

my.cnf สำหรับแรม 4GB แบบใช้ทั่วๆ ไปครับ

[mysqld]
local-infile=0

innodb_buffer_pool_size=256Minnodb_additional_mem_pool_size=4M
innodb_log_buffer_size=2M
innodb_flush_log_at_trx_commit = 1
innodb_thread_concurrency=2
innodb_log_file_size = 256M
innodb_file_per_table

skip-name-resolve
max_connections = 300
key_buffer = 384M
myisam_sort_buffer_size = 32M
join_buffer_size = 1M
read_buffer_size = 1M
sort_buffer_size = 2M
read_rnd_buffer_size = 1M

table_cache = 1536
thread_cache = 4
thread_concurrency = 2
thread_cache_size = 256
wait_timeout = 3600
connect_timeout = 10
max_tmp_tables = 256
tmp_table_size = 128M
max_allowed_packet = 16M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 32M
query_cache_type = 1
query_prealloc_size = 16384
query_alloc_block_size = 16384
max_heap_table_size = 128M
#tmpdir=/var/mysqltmp

log_warnings=0

ขอบคุณครับ

index ต้องทำครับ ความสำคัญมันไม่ได้อยู่ตรงว่าข้อมูลมีได้กี่แบบครับ
ความสำคัญมันอยู่ตรงที่ถ้ามีการ query โดยใช้ field ไหนเป็น key โดยที่ไม่มี index มันก็ต้องไปวิ่งหาในทุก record (row) ซึ่งอยู่บน disk ครับ ซึ่งต่างกับการวิ่งหาใน index อยู่โหลดเก็บไว้ในแรม
และการวิ่งไปบน disk เยอะๆ ก็เป็นที่มาของ %wa (IO Wait) กับ disk util% ที่เยอะๆนั่นแหละครับ สาเหตุโดยตรงเลย

log queries not using index อยู่ในไฟล์เดียวกับ slow log ครับ ลองสังเกตอันที่มัน query time เป็น 0 ครับ

index เอาง่ายๆ เลยนะครับ กวาด query ออกมา แล้ว

อะไรหลัง SELECT ใส่ index ให้หมดเลยครับ เหนื่อยหน่อย แต่หายเกือบหมดแน่ๆ

แจ้งความคืบหน้านะครับ เมื่อคืนผมนั่งแก้ index อยู่นาน โดยดูจาก slow.mysql.log อันไหนช้าก็แก้ไปตามที่คิดว่าควรจะแก้ ไม่ได้ใส่ทุกอันเพราะเห็นเขาว่าใส่ index เยอะก็ไม่ดีสำหรับตารางที่ update บ่อย

พอวันนี้มาดูผลตอนเที่ยงคนเริ่มเข้าเยอะอาการก็ยังคล้ายๆเดิม load ก็ขึ้นไปที่เกือบ 100 ดูเหมือนว่ามันจะไม่ค่อยได้ผลนะครับ หรือเพราะยังทำได้ไม่ดีพอก็ไม่แน่ใจ คงต้องงมและทดสอบอีกซักพักในเรื่องนี้

แต่ที่ได้ผลและตอนนี้ทุกอย่างดูเหมือนจะดีขึ้นได้จากการ แก้ไขไฟล์ my.cnf และ httpd.conf

  • my.cnf ตอนแรกมีแค่ 2 บรรทัด ตอนนี้ก๊อบของคุณ icez มาใส่เลย
  • ส่วน httpd.conf ผมก็ไม่มี พวก MaxClients StartServers ServerLimit ให้ปรับเหมือนชาวบ้านเขาอีก ผมก็เลยไปก๊อบจากในเน็ตมาใส่ที่ท้ายไฟล์ดื้อๆเลย และก็แก้ เฉพาะ MaxClients กับ ServerLimit ไว้ที่ 80-100 ตามที่แนะนำมา

ทดสอบตอนคนเข้าเยอะพบว่าถ้าตั้งไว้ที่ 100 แก้ปัญหา load average ได้ชัดเจนมาก แต่พอเข้าเว็บมันจะช้า ไม่ว่าจะคลิก link ไหนมันจะโหลดนานข้อมูลถึงจะขึ้น ตอนนี้ผมแก้เป็น 300 load average เพิ่มขึ้นมา แต่เข้าหน้าเว็บได้เร็วตามปกติ

อันนี้คือที่ใส่ไปครับ ไม่รู้ว่าค่าไหนคืออะไร ผมก๊อบเขามา แก้แค่ตรง MaxClients ตามที่แนะนำมา

<IfModule prefork.c>
StartServers 8
MinSpareServers 15
MaxSpareServers 40
ServerLimit 300
MaxClients 300
MaxRequestsPerChild 0
</IfModule>

<IfModule worker.c>
StartServers 2
MaxClients 300
MinSpareThreads 10
MaxSpareThreads 35
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>

เดี๋ยวต้องดูตอนเย็นที่คนเข้าเยอะจริงๆว่าจะเป็นยังไง แล้วจะแจ้งความคืบหน้าอีกครั้ง

ยังไงก็ขอบคุณทุกคนมากครับ เป็นประโยชน์กับผมมากจริงๆ

ถ้า DA มันจะอยู่ในไฟล์ /etc/httpd/conf/extra/httpd-mpm.conf นะครับ

ใช้แค่ใน section prefork ครับ ส่วน worker ลืมมันไปได้เลย ไม่เกี่ยวกันครับ

ถ้าไงลองดูผล top ประกอบด้วยครับว่า cpu มันขึ้นที่ %wa เท่าไหร่ อันนั้นคือ io ครับ

ส่วน index แนะนำให้ใส่ไปให้หมดก่อนครับ แล้วค่อยมาทยอยเอาออกถ้ามันช้า เพราะบางทีเราเห็นมัน query time ต่ำๆแค่ 1-2 วิ แต่มันดันมี query แบบนั้นเยอะมาก พอรวมกันหมดแล้วกลายเป็นว่ามันก็กิน io ไปเยอะมากครับ

ป.ล. ถ้าใส่ index ถูกต้องแล้ว ตรง row_examined จะต้องไม่เกินจำนวน row ที่เรา select ออกมาครับ อย่างเช่นถ้าคิวรี่ที่มี where ไปตรง 20 row ไอ่ตรง row_examined ก็ต้องไม่เกินนั้นครับ (ไม่นับกรณี join อันนั้นจะเพิ่มขึ้นแบบเอา 2 table มาจอยกันครับ)

จากที่ทดสอบวันนี้นะครับ ถ้าเอา MaxClients ใส่ไว้ เครื่องไม่โหลดขึ้นสูงมากแล้ว
แต่ถ้าเอาออก ซักพัก โหลดก็ขึ้นไปเป็นร้อย แม้ว่า Key Efficiency: 99.9% แล้ว