พูลของ memcache daemons สามารถใช้เพื่อแบ่งเซสชันได้อย่างมีประสิทธิภาพมากขึ้นหรือไม่?


25

เรากำลังย้ายจากการตั้งค่าเว็บเซิร์ฟเวอร์ 1 รายการเป็นการตั้งค่าเว็บเซิร์ฟเวอร์สองรายการและฉันต้องเริ่มต้นแบ่งปันเซสชัน PHP ระหว่างเครื่องโหลดบาลานซ์สองเครื่อง เราได้ติดตั้งmemcachedแล้ว ( และเริ่มต้น ) และดังนั้นฉันจึงประหลาดใจที่ฉันสามารถแบ่งปันเซสชันระหว่างเซิร์ฟเวอร์ใหม่ได้สำเร็จโดยการเปลี่ยนเพียง 3 บรรทัดในphp.iniไฟล์ (the session.save_handlerและsession.save_path ):

ฉันแทนที่:

session.save_handler = files

ด้วย:

session.save_handler = memcache

จากนั้นในเว็บเซิร์ฟเวอร์หลักฉันตั้งค่าsession.save_pathให้ชี้ไปที่ localhost:

session.save_path="tcp://localhost:11211"

และในเว็บเซิร์ฟเวอร์ทาสฉันตั้งค่าsession.save_pathให้ชี้ไปที่ต้นแบบ:

session.save_path="tcp://192.168.0.1:11211"

งานเสร็จแล้วฉันทดสอบและใช้งานได้ แต่...

เห็นได้ชัดว่าการใช้ memcache หมายถึงเซสชันอยู่ใน RAM และจะหายไปหากรีบูตเครื่องหรือ memcache daemon ขัดข้อง - ฉันกังวลเล็กน้อยจากเรื่องนี้ แต่ฉันกังวลเล็กน้อยเกี่ยวกับการรับส่งข้อมูลเครือข่ายระหว่างสองเว็บเซิร์ฟเวอร์ (โดยเฉพาะอย่างยิ่ง เราขยายขนาดขึ้น) เพราะเมื่อใดก็ตามที่มีใครโหลดสมดุลกับเว็บเซิร์ฟเวอร์ทาสเซสชันของพวกเขาจะถูกดึงข้ามเครือข่ายจากเว็บเซิร์ฟเวอร์หลัก ฉันสงสัยว่าฉันสามารถกำหนดสองsave_pathsเครื่องเพื่อให้ดูในที่เก็บเซสชันของตนเองก่อนที่จะใช้เครือข่าย ตัวอย่างเช่น:

ปริญญาโท:

session.save_path="tcp://localhost:11211, tcp://192.168.0.2:11211"

ทาส:

session.save_path="tcp://localhost:11211, tcp://192.168.0.1:11211"

สิ่งนี้จะช่วยให้ประสบความสำเร็จในการแชร์เซสชันข้ามเซิร์ฟเวอร์และช่วยในเรื่องประสิทธิภาพหรือไม่? ie บันทึกการรับส่งข้อมูลเครือข่าย 50% ของเวลา หรือเป็นเทคนิคนี้สำหรับ failover เท่านั้น (เช่นเมื่อ memcache daemon ไม่สามารถเข้าถึงได้)?

หมายเหตุ : ฉันไม่ได้ถามเฉพาะเกี่ยวกับการจำลองแบบ memcache โดยเฉพาะ - เพิ่มเติมเกี่ยวกับไคลเอนต์ PHP memcache ที่สามารถสูงสุดภายใน memcache daemon แต่ละตัวในพูลกลับเซสชั่นถ้าพบหนึ่งและสร้างเซสชั่นใหม่หากไม่พบ ในร้านค้าทั้งหมด ขณะที่ฉันกำลังเขียนสิ่งนี้ฉันคิดว่าฉันกำลังขออะไรจาก PHP มาก ๆ ฮ่า ๆ ๆ

สมมติว่า : ไม่มีเซสชันแบบติดหนึบ, การปรับสมดุลโหลดรอบ, เซิร์ฟเวอร์ LAMP


1
เอกสารแนะนำ Memcache ไม่แนะนำให้ใช้ Memcache สำหรับที่เก็บข้อมูลเซสชัน ดูcode.google.com/p/memcached/wiki/… !

คำตอบ:


37

ข้อจำกัดความรับผิดชอบ: คุณเป็นบ้าที่จะฟังฉันโดยไม่ต้องทำการทดสอบมากมายและรับความเห็นที่สองจากคนที่ผ่านการรับรอง - ฉันยังใหม่กับเกมนี้

แนวคิดการปรับปรุงประสิทธิภาพที่เสนอในคำถามนี้จะไม่ทำงาน ข้อผิดพลาดหลักที่ฉันทำคือการคิดว่าลำดับที่ร้าน memcached ถูกกำหนดไว้ในพูลสั่งให้จัดลำดับความสำคัญบางอย่าง นี้ไม่ได้เป็นกรณีที่ เมื่อคุณกำหนดกลุ่มของ daemons ที่จำไว้ (เช่นใช้session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211") คุณจะไม่รู้ว่าจะใช้ร้านค้าใด ข้อมูลมีการกระจายอย่างสม่ำเสมอหมายความว่ารายการอาจถูกเก็บไว้ในรายการแรกหรืออาจเป็นรายการสุดท้าย (หรืออาจเป็นทั้งคู่หากไคลเอ็นต์ memcache ได้รับการกำหนดค่าให้ทำซ้ำ - โปรดทราบว่ามันเป็นไคลเอนต์ที่จัดการกับการจำลองแบบ ไม่ทำเอง) ไม่ว่าจะด้วยวิธีใดก็ตามหมายความว่าการใช้ localhost เป็นรายแรกในพูลจะไม่ปรับปรุงประสิทธิภาพ - มีโอกาส 50% ที่จะชนร้านค้าทั้งสอง

หลังจากทำการทดสอบและการวิจัยเล็กน้อยฉันได้ข้อสรุปว่าคุณสามารถแชร์เซสชันผ่านเซิร์ฟเวอร์โดยใช้ memcache แต่คุณอาจไม่ต้องการ - มันดูเหมือนจะไม่เป็นที่นิยมเพราะมันไม่ขยายและใช้งานร่วมกัน ฐานข้อมูลที่ไม่แข็งแกร่ง ฉันขอขอบคุณข้อเสนอแนะเกี่ยวกับเรื่องนี้เพื่อให้ฉันสามารถเรียนรู้เพิ่มเติม ...

ไม่ต้องสนใจสิ่งต่อไปนี้เว้นแต่คุณมีแอพ PHP:


เคล็ดลับที่ 1: หากคุณต้องการแชร์เซสชันใน 2 เซิร์ฟเวอร์โดยใช้ memcache

ให้แน่ใจว่าคุณตอบใช่เพื่อ " เปิดใช้งานการสนับสนุนตัวจัดการเซสชัน memcache? " เมื่อคุณติดตั้งไคลเอนต์ PHP memcache และเพิ่มต่อไปนี้ใน/etc/php.d/memcache.iniไฟล์ของคุณ:

session.save_handler = memcache

บนเว็บเซิร์ฟเวอร์ 1 (IP: 192.168.0.1):

session.save_path="tcp://192.168.0.1:11211"

บนเว็บเซิร์ฟเวอร์ 2 (IP: 192.168.0.2):

session.save_path="tcp://192.168.0.1:11211"

เคล็ดลับที่ 2: หากคุณต้องการแบ่งปันเซสชันทั่วทั้ง 2 เซิร์ฟเวอร์โดยใช้ memcache และมีการสนับสนุนการทำงานล้มเหลว:

เพิ่มสิ่งต่อไปนี้ใน/etc/php.d/memcache.iniไฟล์ของคุณ:

memcache.hash_strategy = consistent
memcache.allow_failover = 1

บนเว็บเซิร์ฟเวอร์ 1 (IP: 192.168.0.1):

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

บนเว็บเซิร์ฟเวอร์ 2 (IP: 192.168.0.2):

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

หมายเหตุ:

  • นี่เป็นการเน้นย้ำข้อผิดพลาดอื่นที่ฉันทำในคำถามเดิม - ฉันไม่ได้ใช้สิ่งเดียวกันsession.save_pathบนเซิร์ฟเวอร์ทั้งหมด
  • ในกรณีนี้ "failover" หมายความว่าหนึ่ง memcache daemon ล้มเหลวไคลเอนต์ PHP memcache จะเริ่มใช้อีกอัน คือทุกคนที่มีเซสชั่นของพวกเขาในร้านที่ล้มเหลวจะถูกออกจากระบบ ไม่ใช่ความล้มเหลวที่โปร่งใส

เคล็ดลับ 3: หากคุณต้องการแชร์เซสชันโดยใช้ memcache และมีการสนับสนุนการเฟลโอเวอร์แบบโปร่งใส:

เหมือนกับเคล็ดลับ 2 ยกเว้นคุณต้องเพิ่มสิ่งต่อไปนี้ใน/etc/php.d/memcache.iniไฟล์ของคุณ:

memcache.session_redundancy=2

หมายเหตุ:

  • สิ่งนี้ทำให้ไคลเอนต์ memcache ของ PHP เขียนเซสชันไปยังเซิร์ฟเวอร์ 2 เครื่อง คุณได้รับความซ้ำซ้อน (เช่น RAID-1) เพื่อให้การเขียนถูกส่งไปยังมิเรอร์และความล้มเหลวget'sจะถูกลองใหม่บนมิรเรอร์ นี่หมายความว่าผู้ใช้จะไม่สูญเสียเซสชันของตนในกรณีที่ memcache daemon ล้มเหลวหนึ่งครั้ง
  • การเขียนแบบมิร์เรอร์นั้นทำแบบขนาน (โดยใช้ non-blocking-IO) ดังนั้นความเร็วจะไม่ลดลงมากเท่าจำนวนมิเรอร์ที่เพิ่มขึ้น อย่างไรก็ตามการรับส่งข้อมูลเครือข่ายจะเพิ่มขึ้นหากมิเรอร์ memcache ของคุณกระจายอยู่ในเครื่องที่แตกต่างกัน ตัวอย่างเช่นไม่มีโอกาส 50% ที่จะใช้ localhost และหลีกเลี่ยงการเข้าถึงเครือข่าย
    • เห็นได้ชัดว่าความล่าช้าในการจำลองแบบการเขียนสามารถทำให้ข้อมูลเก่าถูกเรียกคืนแทนที่จะพลาดแคช คำถามคือสิ่งนี้มีความสำคัญต่อการสมัครของคุณหรือไม่? คุณเขียนข้อมูลเซสชันบ่อยเพียงใด
  • memcache.session_redundancyมีไว้สำหรับการทำซ้ำซ้อนของเซสชัน แต่ยังมีmemcache.redundancyตัวเลือก ini ที่สามารถใช้งานได้โดยรหัสแอปพลิเคชัน PHP ของคุณหากคุณต้องการให้มีระดับความซ้ำซ้อนที่แตกต่างกัน
  • คุณต้องมีเวอร์ชันล่าสุด (ยังอยู่ในช่วงเบต้าในขณะนี้) ของไคลเอนต์ memcache PHP - เวอร์ชัน 3.0.3 จาก peclทำงานให้ฉัน

คุณสามารถแสดงความคิดเห็นเกี่ยวกับ "มันไม่ได้ปรับขนาดเช่นเดียวกับการใช้ฐานข้อมูลที่แชร์" ฉันไม่เห็นว่ามันแตกต่างจากการตั้งค่า DB master-slave ทั่วไปอย่างไร ขอบคุณ!
Boy Baukema

นี่คือการวิเคราะห์ที่ยอดเยี่ยมถึงแม้ว่าจะมีข่าวลือ (รายงานข้อผิดพลาดหรือที่รู้จัก) ว่ามันไม่ทำงานอย่างที่คาดไว้เมื่อคุณใช้ext/memcacheเวอร์ชัน 3.x เรากำลังเล่นกับตัวเลือกนั้นเช่นกันและฉันตัดสินใจวนลูปรายชื่อเซิร์ฟเวอร์และเขียนด้วยตัวเอง
จนถึง

ในกรณีที่มีเคล็ดลับ 3: จะเกิดอะไรขึ้นถ้าโฮสต์ memcached หนึ่งหายไปจากนั้นโฮสต์จะหายไปจากนั้นโฮสต์วินาทีก็จะลดลง เท่าที่ฉันเข้าใจ - จะไม่มีการกู้คืนข้อมูลเซสชันและบางส่วนจะสูญหายใช่ไหม
GioMac

28

Re: เคล็ดลับ 3 ข้างต้น (สำหรับคนอื่นที่บังเอิญพบปัญหานี้ผ่าน Google) ดูเหมือนว่าอย่างน้อยในปัจจุบันเพื่อให้สามารถใช้งานได้คุณต้องใช้memcache.session_redundancy = N+1สำหรับเซิร์ฟเวอร์ N ในกลุ่มของคุณอย่างน้อยก็น่าจะเป็นเกณฑ์ขั้นต่ำ คุณค่าที่ได้ผล (ทดสอบด้วย php 5.3.3 ในเสถียรภาพเดเบียน, PECL memcache 3.0.6, สองเซิร์ฟเวอร์ memcached. session_redundancy=2จะล้มเหลวทันทีที่ฉันปิดเซิร์ฟเวอร์แรกในsave_path, session_redundancy=3ปรับการทำงาน.)

ดูเหมือนว่าจะถูกจับในรายงานบั๊กเหล่านี้:


1
ไม่สามารถ upvote คุณพอ ..
เทศกาล

1
ฉันดีใจที่ฉันเลื่อนลง นี่เป็นปัญหา
Daren Schwenke

ไม่ชัดเจนสำหรับฉันคุณลักษณะนี้มีเฉพาะใน PECL memcache 3.x series เท่านั้นหรือไม่ ทั้งหมดเหล่านี้มีการระบุไว้ในซอฟต์แวร์เบต้าบนpecl.php.net/package/memcacheในขณะที่ 2.2.7 ถ้าฉันฆ่าเซิร์ฟเวอร์ที่ฉันเห็นผู้นำอยู่ทุกอย่างก็ตาย
โจ

เป็นเวลาหลายปีแล้วที่ฉันได้ดูเรื่องนี้พูดตามตรง ในขณะที่ฉันจำได้มันเป็นคุณสมบัติ 3.x (icbw) เราปรับใช้ระบบจำนวนมากโดยใช้ปลั๊กอิน "รุ่นเบต้า" (บางระบบมีปริมาณการใช้งานค่อนข้างสูง) และไม่มีปัญหาใด ๆ ที่เกี่ยวข้อง YMMV, ทดสอบสิ่งต่าง ๆ ก่อนที่พวกเขาจะขึ้นแสดงสด ฯลฯ :) ฉันไม่ได้ทำงานใน PHP มาสองสามปีแล้วดังนั้นจุดที่ดีขึ้นของเรื่องไม่สำคัญก็เริ่มจางหายไป
Michael Jackson

3

พร้อมกับการตั้งค่า php.ini ที่แสดงด้านบนให้แน่ใจว่ามีการตั้งค่าต่อไปนี้ด้วย:

memcache.allow_failover = 1  
memcache.hash_strategy = 'consistent'

จากนั้นคุณจะได้รับความล้มเหลวเต็มรูปแบบและความซ้ำซ้อนฝั่งไคลเอ็นต์ caveat ด้วยวิธีการนี้คือว่าถ้า memcached ไม่ทำงานบน localhost จะมีการพลาดการอ่านก่อนที่ไคลเอ็นต์ php memcache จะพยายามเซิร์ฟเวอร์ถัดไปในพูลที่ระบุใน session.save_path

เพียงจำไว้ว่าสิ่งนี้มีผลต่อการตั้งค่าส่วนกลางสำหรับไคลเอ็นต์ memcache php ที่ทำงานบนเว็บเซิร์ฟเวอร์


การใช้consistentกลยุทธ์การแปลงแป้นพิมพ์มีเหตุผลหรือไม่เนื่องจากความsession.save_pathแตกต่างของแต่ละเว็บเซิร์ฟเวอร์
Tom

1

memcached ไม่ทำงานอย่างนั้น (โปรดแก้ไขฉันหากฉันผิด!)

หากคุณต้องการให้แอปพลิเคชันของคุณมีที่เก็บข้อมูลเซสชันซ้ำซ้อนคุณต้องสร้างสิ่งที่เปลี่ยนแปลง / เพิ่ม / ลบรายการให้กับทั้งสองอินสแตนซ์ memcached memcached ไม่ได้จัดการสิ่งนี้สิ่งเดียวที่มีคือการเก็บคีย์แฮช ดังนั้นจึงไม่มีการจำลองแบบการซิงโครไนซ์ไม่มีอะไรเลย nada

ฉันหวังว่าฉันจะไม่ผิดในเรื่องนี้ แต่นี่คือสิ่งที่ฉันรู้ของ memcached ได้ไม่กี่ปีนับตั้งแต่ฉันสัมผัสมัน


มันจะมีประโยชน์สำหรับฉันถ้าคุณผิด :-) มีบทความในphpslacker.com ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ) ซึ่งแนะนำ memcached สามารถทำงานได้ตามที่อธิบายไว้ในคำถาม อาจขึ้นอยู่กับว่าลูกค้า memcache ใช้กลยุทธ์การแฮช
Tom

1
memcache ไม่ทำงานอย่างนั้น แต่ดูเหมือนว่า php สามารถทำงานได้ตามที่คุณต้องการ คุณจะต้องเปลี่ยน php.ini หรือเปลี่ยนแอพตามที่อธิบายไว้ จากบล็อก: การจัดกลุ่มของคุณถามที่ดีความจริงจะบอกว่าไม่มี สิ่งที่เรามีคือ memcache pool ประกอบด้วย 2 เซิร์ฟเวอร์ PHP ได้รับการกำหนดค่าให้เขียนลงในพูล PHP อ่าน / เขียนไปยังกลุ่มเซิร์ฟเวอร์ตามลำดับที่ระบุโดยคำสั่ง“ session.save_path” ini สำหรับการอ่าน PHP จะขอวัตถุแคชโดยคีย์จากกลุ่ม เนื่องจาก“ failover” ถูกเปิดใช้งาน PHP จะทำการค้นหาพูลของเซิร์ฟเวอร์ memcache แบบ
ตัวต่อตัว

1

memcached ไม่ได้ทำซ้ำออกจากกล่อง แต่repcached (memcached ที่แก้ไขแล้ว) ทำ อย่างไรก็ตามหากคุณใช้ mysql อยู่แล้วทำไมไม่ใช้ฟังก์ชั่นการจำลองแบบกับการจำลองแบบต้นแบบหลักและรับประโยชน์จากการจำลองข้อมูลแบบเต็ม

ซี


ขอบคุณสำหรับข้อมูล. มันไม่ใช่การจำลองแบบที่ฉันตามมาจริงๆ มันเป็นเรื่องของความต้องการที่จะจุดสูงสุดในแต่ละ memcached ในทางกลับกันจนกว่าจะพบเซสชั่น นั่นคือการตรวจสอบ localhost ก่อนเพราะมันเร็วที่สุดแล้วตรวจสอบเซิร์ฟเวอร์อื่นต่อไป
Tom

1
ในนามของเทพเจ้าทั้งหมดทำไม ???? นี่เป็นทางออกที่ผิดไปทั้งหมด .... ดีเพียงเกี่ยวกับปัญหาใด ๆ ที่ฉันสามารถคิด นอกจากจะไม่มีประสิทธิภาพมากแม้จะมีเพียง 2 เซิร์ฟเวอร์ประสิทธิภาพจะแย่ลงอย่างรวดเร็วหากคุณเพิ่มเซิร์ฟเวอร์มากขึ้น และนั่นไม่ได้พิจารณาถึงความจริงที่ว่าโซลูชันของคุณทำให้เกิดการขัดข้องสองเท่าเช่นเดียวกับที่ใช้กับเซิร์ฟเวอร์เดียวเมื่อเพิ่มการใช้งานเซิร์ฟเวอร์ในคลัสเตอร์ควรลดความน่าจะเป็นของการหยุดทำงาน (BTW ถ้าคุณหมายถึงการปัดเศษ DNS ที่อิง DNS
ดังนั้นการเชื่อมโยง

ขอบคุณสำหรับข้อเสนอแนะใช่ฉันยอมรับอย่างอิสระว่าฉันเป็น noob ในการแบ่งปันเซสชัน! :-) อย่างไรก็ตามฉันยังไม่เข้าใจว่าทำไมข้อเสนอของฉันจึงน่าเกลียด ฉันคิดว่ามันจะมีประสิทธิภาพมากกว่าการใช้ฐานข้อมูลที่ใช้ร่วมกันและฉันก็คิดว่ามันจะทำให้เกิดการขัดข้องน้อยกว่า
Tom

ไม่มันทำให้พวกเขามีโอกาสมากขึ้น การรวมข้อมูลเช่นนี้เหมาะสมเมื่อคุณมีโหนดจำนวนมากเนื่องจากคุณลดจำนวนการเรพลิเคท แต่โดยทั่วไปจะทำการเรพลิเคทบางอย่างด้วยจำนวนพูลที่กำหนดเพื่อรักษาความพร้อมใช้งาน คุณจะต้องพิถีพิถันมากเกี่ยวกับประสิทธิภาพเพื่อดูความแตกต่างระหว่างการจำลองแบบ repcached และการจำลองแบบ mysqld
symcbean

ฉันได้ทดสอบและยืนยันว่าตราบใดที่ฉันกำลังใช้ allow_failover = 1 กระจกหลาย ๆ ตัวก็จะทำให้ LESS ขัดข้อง ฉันสามารถปิดมิเรอร์หนึ่งรีสตาร์ทและปิดอีกรีสตาร์ทและปิดอีกครั้ง - ทั้งหมดโดยไม่ต้องออกจากระบบ ฉันเดาไคลเอนต์ memcache ของ PHP กำลังใช้กลอุบายมากมายเบื้องหลัง
Tom
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.