load average มันสูง ไม่ทราบว่าเกิดจากอะไร ตรง database ก็ทำ index แล้ว
- ขอดู query เต็มๆหน่อย
- ทำ 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% แล้ว