Terkait dengan: Kebijakan terkini tentang SQL Server dan Hyperthreading
Baru-baru ini kami memutakhirkan server database Windows 2008 R2 kami dari X5470 ke X5560 . Teorinya adalah kedua CPU memiliki kinerja yang sangat mirip, jika apa pun X5560 sedikit lebih cepat.
Namun, kinerja SQL Server 2008 R2 telah sangat buruk selama beberapa hari terakhir dan penggunaan CPU telah cukup tinggi.
Harapan hidup halaman sangat besar, kami mendapatkan hit cache hampir 100% untuk halaman, jadi memori tidak menjadi masalah.
Ketika saya berlari:
SELECT * FROM sys.dm_os_wait_stats
order by signal_wait_time_ms desc
Saya mendapatkan:
wait_type waiting_tasks_count wait_time_ms max_wait_time_ms signal_wait_time_ms -------------------------------------------------- ---------- -------------------- -------------------- -------------------- -------------------- XE_TIMER_EVENT 115166 2799125790 30165 2799125065 REQUEST_FOR_DEADLOCK_SEARCH 559393 2799053973 5180 2799053973 SOS_SCHEDULER_YIELD 152289883 189948844 960 189756877 CXPACKET 234638389 2383701040 141334 118796827 SLEEP_TASK 170743505 1525669557 1406 76485386 LATCH_EX 97301008 810738519 1107 55093884 LOGMGR_QUEUE 16525384 2798527632 20751319 4083713 WRITELOG 16850119 18328365 1193 2367880 PAGELATCH_EX 13254618 8524515 11263 1670113 ASYNC_NETWORK_IO 23954146 6981220 7110 1475699 (10 baris terpengaruh)
Saya juga berlari
-- Isolate top waits for server instance since last restart or statistics clear
WITH Waits AS (
SELECT
wait_type,
wait_time_ms / 1000. AS [wait_time_s],
100. * wait_time_ms / SUM(wait_time_ms) OVER() AS [pct],
ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS [rn]
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE',
'SLEEP_TASK','SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH','WAITFOR','LOGMGR_QUEUE',
'CHECKPOINT_QUEUE','REQUEST_FOR_DEADLOCK_SEARCH','XE_TIMER_EVENT','BROKER_TO_FLUSH',
'BROKER_TASK_STOP','CLR_MANUAL_EVENT','CLR_AUTO_EVENT','DISPATCHER_QUEUE_SEMAPHORE',
'FT_IFTS_SCHEDULER_IDLE_WAIT','XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN'))
SELECT W1.wait_type,
CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
INNER JOIN Waits AS W2 ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING SUM(W2.pct) - W1.pct < 95; -- percentage threshold
Dan mendapatkan
wait_type wait_time_s pct running_pct CXPACKET 554821.66 65.82 65.82 LATCH_EX 184123.16 21.84 87.66 SOS_SCHEDULER_YIELD 37541.17 4.45 92.11 PAGEIOLATCH_SH 19018.53 2.26 94.37 FT_IFTSHC_MUTEX 14306.05 1.70 96.07
Itu menunjukkan sejumlah besar waktu menyinkronkan kueri yang melibatkan paralelisme (CXPACKET tinggi). Selain itu, secara anekdot banyak dari kueri masalah ini dieksekusi pada banyak core (kami tidak memiliki petunjuk MAXDOP di mana pun dalam kode kami)
Server belum dimuat selama lebih dari satu hari atau lebih. Kami mengalami banyak variasi dengan eksekusi kueri, biasanya banyak kueri tampak lebih lambat daripada yang ada di server DB kami sebelumnya dan CPU sangat tinggi.
Akankah menonaktifkan Hyperthreading membantu mengurangi penggunaan CPU kami dan meningkatkan throughput?
sumber
Jawaban:
Saya masih merasa bahwa menguji beban kerja spesifik Anda , sesuai jawaban asli, adalah satu-satunya cara untuk memastikan. Ini bukan jawaban yang ideal ketika Anda mencoba untuk menyetel sistem produksi (jadi saya akan bertanya apakah mungkin untuk mendapatkan testbed identik dalam sistem di mana baik kinerja dan ketersediaan sangat penting) tetapi itu satu-satunya yang saya sangat nyaman dengan.
Kita dapat berbicara tentang teori apakah Hyperthreading harus melukai atau meningkatkan hal-hal secara umum (saya merasa lebih cenderung terluka daripada bantuan pada server sehingga untuk penyebaran "generik" saya mungkin menonaktifkannya), tetapi ada hanya satu cara untuk memastikan apakah itu akan membuat perbedaan dalam kasus spesifik Anda, dan itu adalah coba dan lihat.
sumber
Saya setuju itu
Sepertinya kita harus menyetel dua hal:
MAXDOP (Derajat Maksimal Paralelisme). Semua yang saya baca menunjukkan bahwa memiliki batasan ini mungkin merupakan ide yang buruk, dan dokumentasi Microsoft mengatakan:
sesuatu yang lebih tinggi daripada
8
umumnya tidak disarankan .. jadi saya atur4
untuk saat ini. Awalnya nol (tidak terikat).Ambang Batas Biaya untuk Paralelisme. Rupanya default di
5
sini dianggap sebagai default yang cukup rendah menurut beberapa posting SQL MVP yang saya temukan - kita dapat menyetelnya untuk mengurangi berapa banyak paralelisme yang bahkan dicoba oleh scheduler.Tapi jujur ini terasa seperti solusi; Saya pikir solusi sebenarnya untuk beban kerja kami (indeks teks lengkap berat) adalah untuk menonaktifkan HT.
sumber
Anandtech menemukan bahwa dengan beban baca murni, itu sedikit sakit, dan dengan beban tulis yang berat, itu sedikit menang. Saya belum melihat apa pun yang membuat saya berpikir itu akan membuat Anda mendapat pukulan yang jauh lebih buruk daripada -5%, atau kemenangan yang jauh lebih baik dari 15%. Perhatikan apa yang terjadi dengan Atom, ini adalah kemenangan besar, tetapi itu adalah cpu yang sangat aneh.
Yang Anda ubah hanyalah cpu? Anda beralih dari 12MB cache dan 4 thread, jadi 3MB cache per thread, menjadi 8 MB cache, dan 8 thread, jadi 1MB per thread. Nah, itu terlalu menyederhanakan, tapi saya yakin itulah yang membunuh Anda, Anda dulu menjalankan kueri dalam cache, dan sekarang menjalankannya dari RAM karena mereka membutuhkan lebih dari 1MB tetapi kurang dari 3MB. Mematikan HT mungkin akan membantu, tapi saya akan kembali ke CPU lama. Matikan HT, dan Anda mendapatkan 2MB per utas, tetapi jika beban kerja Anda terlalu banyak, itu tidak akan membantu. Mungkin cpu cache 12MB yang lama sangat cepat untuk beban kerja Anda.
Saya akan mencoba mematikan HT, dan melihat apakah itu merupakan peningkatan, tapi saya menduga cache adalah raja untuk beban kerja Anda, dan Anda mungkin perlu kembali ke chip 12 MB.
sumber
Hyperthreading, paling-paling, hanyalah cara mengabstraksi tugas beralih dari sistem operasi dan meletakkannya di-mati, dengan akses langsung ke cache L1 dan L2, yang membuat tugas beralih crapload lebih cepat.
Pengujian dengan VMWare menunjukkan bahwa penonaktifan HT tidak membuat perbedaan nyata pada beban standar, dan kenaikan 5% di bawah beban berat, karena fakta bahwa ESXi cukup pintar untuk mengetahui perbedaan antara utas "nyata" dan utas "palsu" (Ada banyak hal lebih dari itu, tapi itu dalam istilah awam). SQL Server 2005 tidak secerdas itu, tetapi dikombinasikan dengan sistem operasi terbaru harus ada sedikit keuntungan untuk menonaktifkan HT.
Semua yang dikatakan, saya setuju dengan Ronald bahwa itu kemungkinan besar akan menjadi cache L2 Anda. Penurunan 33% dalam ukuran cache adalah besar, dan ketika kami menentukan SQL Server kami, kami selalu mencari cache lebih dari kecepatan clock mentah setiap waktu.
sumber
Berdasarkan pengalaman saya, HT membuat operasi I / O selamanya pada node aktif saya pada Windows 2008 R2 Cluster (menjalankan SQL Server 2008 R2). Fakta yang menarik adalah bahwa hal itu tidak tercermin dalam statistik tunggu maupun dalam pssdiag yang saya jalankan untuk dukungan Microsoft.
Cara saya perhatikan I / O rendah hanya dengan menonton penghitung OS untuk disk fisik. Seperti yang ditunjukkan Sam, saya menulisnya di sini dan di sini
Jika Anda TIDAK mengalami masalah I / O dan terikat dengan CPU, saya sarankan Anda memulai dengan cara ini:
Tentukan proses dan blok T-SQL mana yang paling banyak memanfaatkan CPU. Dalam pengalaman kami, setelah kami memperbaiki masalah dengan I / O (dengan mematikan HT) kami mengidentifikasi kode yang berkinerja buruk pada 2008 R2 dan baik-baik saja pada tahun 2005. Saya menulisnya di sini .
Saat berada di bawah beban tinggi, jalankan sp_whoisactive Adam Machanic. Anda dapat mengunduhnya dari sini . Kami mengalami pemanfaatan CPU yang sangat tinggi karena jumlah pembacaan logis yang berlebihan (20 juta per kueri) karena rencana yang sangat buruk. Proses kami melakukan anti-semi joins dengan tabel yang dipartisi.
Rekomendasi saya berikutnya adalah menjalankan profiler untuk mengidentifikasi satu set kode T-SQL yang keduanya tinggi dalam CPU dan I / O membaca logis.
Dengan langkah-langkah di atas kami dapat menyesuaikan proses yang menyinggung dan beralih dari 85% pemanfaatan CPU berkelanjutan menjadi hampir nol.
Semoga Sukses dan jangan ragu untuk mengirimkan saya garis jika Anda menemukan perbaikan karena saya ingin menambahkan kasus ke blog saya.
Terima kasih
Oscar
sumber
Apakah HT baik atau buruk sulit dijabarkan.
Itu benar-benar tergantung pada pola beban server berdasarkan pengalaman dan membaca. Yaitu, ketika hal itu memengaruhi kinerja, ia melakukannya dengan sangat buruk : jika tidak, Anda tidak menyadarinya.
Teori yang saya baca adalah bahwa thread berbagi cache yang berarti dalam kondisi buruk setiap thread dapat menimpa cache thread lain. Jika Anda tidak memiliki banyak paralelisme, atau beban Anda banyak pertanyaan pendek, maka itu mungkin tidak mempengaruhi Anda.
Saya sudah mencoba dengan MAXDOP dan afinitas prosesor (kembali ke peran DBA nyata terakhir saya di SQL Server 2000) tetapi tidak pernah bisa menemukan sesuatu yang konklusif: tetapi hanya untuk toko saya pada waktu itu.
Sebagai tes cepat, Anda dapat mengatur afinitas prosesor untuk hanya menggunakan inti fisik (angka yang lebih rendah) dan melihat apa yang terjadi.
Namun, paling banyak Anda kehilangan setengah inti Anda. Saat ini mungkin tidak masalah dibandingkan dengan apa yang saya mainkan beberapa tahun yang lalu ketika itu 2 vs 4 atau 4 vs 8. Sekarang 8 vs 16 atau 16 vs 32.
Sunting: Tes oleh Slava Oks
sumber
Sayangnya, saya tidak berpikir Anda akan mendapatkan jawaban yang lebih pasti daripada "coba nonaktifkan hyperthreading dan lihat apakah itu membantu".
Terlepas dari jawaban bermanfaat dari Jonathan di utas asli saya (yang Anda tautkan dalam pertanyaan Anda), saya tidak pernah bisa mendapatkan bukti pasti tentang dampak HT pada server tertentu yang saya selidiki. Dalam kasus saya, server sudah dijadwalkan untuk diganti, jadi kami cukup membiarkan penggantian itu "mengatasi masalah".
Saranku:
Coba pengaturan tingkat Paralelisme MAX Tingkat server 1 . Paralelisme pada SQL paling berguna untuk kueri yang lebih besar dan lebih lama, dan beban Anda (saya asumsikan) terdiri dari sejumlah besar kueri yang lebih kecil. Ini sepenuhnya harus menghilangkan menunggu CXPACKET. Ini dapat membuat kueri individual tertentu berjalan sedikit lebih lama, tetapi harus memungkinkan lebih banyak "throughput" dari total kueri di server.
Saya sudah mendapatkan hasil yang baik melakukan ini di server OLTP. Jenis server lain (server pelaporan, server pemrosesan, data pergudangan) pasti membutuhkan MAXDOP yang ditetapkan lebih tinggi.
Dan hanya untuk memperjelas, pengaturan ini masih memungkinkan SQL untuk menggunakan beberapa utas untuk setiap tabel dalam GABUNGAN, jadi Anda tidak benar-benar menghilangkan paralelisme sepenuhnya.
Setidaknya patut dicoba, karena perubahan pengaturan ini segera berlaku dan bahkan tidak mengharuskan Anda untuk me-restart layanan SQL: http://msdn.microsoft.com/en-us/library/ms181007.aspx
Ini berarti Anda bisa beralih segera kembali jika semuanya mulai masuk neraka.
Mematikan hyperthreading di BIOS akan membutuhkan server reboot penuh, jadi sedikit lebih berisiko.
sumber
Sebagai catatan, kami juga memiliki kinerja buruk yang tidak terduga setelah peningkatan server. Ternyata karena masalah dengan penghematan daya BIOS dan CPU. Pengaturan default pada server (HP) adalah untuk mengabaikan kontrol OS dari kecepatan CPU dan menggunakan algoritma sendiri. Mengubah ini ke kontrol OS, dan memperbarui BIOS, menghasilkan peningkatan yang signifikan. Ada beberapa catatan rilis (tidak dapat menemukannya sekarang) bahwa ada bug BIOS yang mengunci CPU pada kondisi kinerja terendah.
/server//a/196329/6390
sumber