Có thể sử dụng một nhóm các daemon memcache để chia sẻ các phiên hiệu quả hơn không?


25

Chúng tôi đang chuyển từ thiết lập 1 máy chủ web sang thiết lập hai máy chủ web và tôi cần bắt đầu chia sẻ các phiên PHP giữa hai máy cân bằng tải. Chúng tôi đã cài đặt memcached ( và đã bắt đầu ) và vì vậy tôi đã rất ngạc nhiên khi tôi có thể hoàn thành các phiên chia sẻ giữa các máy chủ mới bằng cách chỉ thay đổi 3 dòng trong php.initệp ( session.save_handlersession.save_path ):

Tôi đã thay thế:

session.save_handler = files

với:

session.save_handler = memcache

Sau đó, trên máy chủ web chính, tôi đặt session.save_pathđiểm đến localhost:

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

và trên máy chủ web nô lệ, tôi đặt session.save_pathđiểm đến chủ:

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

Công việc đã hoàn thành, tôi đã thử nghiệm nó và nó hoạt động. Nhưng...

Rõ ràng việc sử dụng memcache có nghĩa là các phiên trong RAM và sẽ bị mất nếu máy được khởi động lại hoặc trình nền memcache gặp sự cố - Tôi hơi lo lắng về điều này nhưng tôi hơi lo lắng về lưu lượng mạng giữa hai máy chủ web (đặc biệt là chúng tôi mở rộng quy mô) bởi vì bất cứ khi nào ai đó tải cân bằng với máy chủ web nô lệ, các phiên của họ sẽ được tìm nạp trên mạng từ máy chủ web chính. Tôi đã tự hỏi nếu tôi có thể định nghĩa hai save_pathsđể các máy tìm trong bộ lưu trữ phiên của riêng chúng trước khi sử dụng mạng. Ví dụ:

Bậc thầy:

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

Nô lệ:

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

Điều này sẽ chia sẻ thành công các phiên trên các máy chủ VÀ giúp hiệu suất? tức là tiết kiệm lưu lượng mạng 50% thời gian. Hoặc kỹ thuật này chỉ dành cho failovers (ví dụ: khi một daemon memcache không thể truy cập được)?

Lưu ý : Tôi không thực sự hỏi cụ thể về sao chép memcache - thêm về việc máy khách memcache PHP có thể đạt đỉnh trong mỗi trình nền memcache trong một pool hay không, trả về một phiên nếu nó tìm thấy một và chỉ tạo một phiên mới nếu nó không tìm thấy một phiên trong tất cả các cửa hàng Khi tôi viết bài này, tôi nghĩ rằng tôi đang hỏi một chút từ PHP, lol ...

Giả sử : không có phiên dính, cân bằng tải vòng tròn, máy chủ LAMP.


1
Tài liệu Memcache không khuyến nghị sử dụng Memcache để lưu trữ phiên. Xem code.google.com/p/memcached/wiki/ Lần !

Câu trả lời:


37

Tuyên bố miễn trừ trách nhiệm: Bạn sẽ tức giận lắng nghe tôi mà không thực hiện nhiều thử nghiệm VÀ nhận được ý kiến ​​thứ 2 từ một người đủ điều kiện - Tôi mới tham gia trò chơi này .

Ý tưởng cải thiện hiệu quả được đề xuất trong câu hỏi này sẽ không hiệu quả. Sai lầm chính mà tôi đã làm là nghĩ rằng thứ tự mà các cửa hàng memcached được xác định trong nhóm quy định một số loại ưu tiên. Đây không phải là trường hợp . Khi bạn xác định một nhóm daemon nhớ (ví dụ như sử dụng session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"), bạn không thể biết cửa hàng nào sẽ được sử dụng. Dữ liệu được phân phối đều, có nghĩa là một mục có thể được lưu trữ trong lần đầu tiên hoặc có thể là mục cuối cùng (hoặc có thể là cả nếu máy khách memcache được cấu hình để sao chép - lưu ý rằng đó là máy khách xử lý sao chép, máy chủ memcached không tự làm). Dù bằng cách nào cũng có nghĩa là sử dụng localhost làm đầu tiên trong nhóm sẽ không cải thiện hiệu suất - có 50% cơ hội trúng một trong hai cửa hàng.

Sau khi thực hiện một chút thử nghiệm và nghiên cứu, tôi đã kết luận rằng bạn CÓ THỂ chia sẻ các phiên trên các máy chủ bằng memcache NHƯNG bạn có thể không muốn - nó dường như không phổ biến vì nó không mở rộng cũng như sử dụng chia sẻ cơ sở dữ liệu tại nó không mạnh bằng. Tôi đánh giá cao phản hồi về điều này để tôi có thể tìm hiểu thêm ...

Bỏ qua những điều sau trừ khi bạn có ứng dụng PHP:


Mẹo 1: Nếu bạn muốn chia sẻ phiên trên 2 máy chủ bằng memcache:

Đảm bảo bạn đã trả lời để " Kích hoạt hỗ trợ trình xử lý phiên memcache? " Khi bạn cài đặt ứng dụng khách memcache PHP và thêm phần sau vào /etc/php.d/memcache.initệp của mình :

session.save_handler = memcache

Trên máy chủ web 1 (IP: 192.168.0.1):

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

Trên máy chủ web 2 (IP: 192.168.0.2):

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

Mẹo 2: Nếu bạn muốn chia sẻ phiên trên 2 máy chủ bằng memcache VÀ có hỗ trợ chuyển đổi dự phòng:

Thêm vào đây vào /etc/php.d/memcache.initập tin của bạn :

memcache.hash_strategy = consistent
memcache.allow_failover = 1

Trên máy chủ web 1 (IP: 192.168.0.1):

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

Trên máy chủ web 2 (IP: 192.168.0.2):

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

Ghi chú:

  • Điều này nhấn mạnh một lỗi khác mà tôi đã mắc phải trong câu hỏi ban đầu - Tôi đã không sử dụng giống hệt nhau session.save_pathtrên tất cả các máy chủ.
  • Trong trường hợp này "failover" có nghĩa là nếu một daemon memcache bị lỗi, máy khách memcache PHP sẽ bắt đầu sử dụng cái kia. tức là bất cứ ai có phiên của họ trong cửa hàng không thành công sẽ bị đăng xuất. Nó không phải là failover minh bạch.

Mẹo 3: Nếu bạn muốn chia sẻ phiên bằng memcache VÀ có hỗ trợ chuyển đổi dự phòng trong suốt:

Tương tự như mẹo 2 ngoại trừ bạn cần thêm phần sau vào /etc/php.d/memcache.initệp của mình :

memcache.session_redundancy=2

Ghi chú:

  • Điều này làm cho máy khách memcache PHP viết các phiên tới 2 máy chủ. Bạn nhận được sự dự phòng (như RAID-1) để ghi được gửi đến n gương và thất bại get'sđược thử lại trên gương. Điều này có nghĩa là người dùng không mất phiên trong trường hợp một lỗi daemon memcache.
  • Việc ghi nhân đôi được thực hiện song song (sử dụng IO không chặn) vì vậy hiệu suất tốc độ không nên giảm nhiều khi số lượng gương tăng lên. Tuy nhiên, lưu lượng truy cập mạng sẽ tăng nếu gương memcache của bạn được phân phối trên các máy khác nhau. Ví dụ: không còn 50% cơ hội sử dụng localhost và tránh truy cập mạng.
    • Rõ ràng, sự chậm trễ trong sao chép ghi có thể khiến dữ liệu cũ được truy xuất thay vì bỏ lỡ bộ đệm. Câu hỏi là liệu điều này có quan trọng với ứng dụng của bạn? Bạn có thường xuyên viết dữ liệu phiên không?
  • memcache.session_redundancydành cho dự phòng phiên nhưng cũng có một memcache.redundancytùy chọn ini có thể được sử dụng bởi mã ứng dụng PHP của bạn nếu bạn muốn nó có mức dự phòng khác.
  • Bạn cần một phiên bản gần đây (vẫn đang trong giai đoạn thử nghiệm tại thời điểm này) của ứng dụng khách memcache PHP - Phiên bản 3.0.3 từ pecl làm việc cho tôi.

Bạn có thể bình luận về "nó không mở rộng quy mô cũng như sử dụng cơ sở dữ liệu dùng chung" không? Tôi không thấy nó khác với thiết lập DB chủ-nô điển hình như thế nào. Cảm ơn!
Cậu bé Baukema

Đây là một sự cố khá thú vị, mặc dù có những tin đồn (còn gọi là báo cáo lỗi) rằng điều này không hoạt động như mong đợi khi bạn sử dụng ext/memcachephiên bản 3.x. Chúng tôi cũng đang chơi với tùy chọn đó và tôi quyết định lặp qua danh sách máy chủ và tự viết thư cho nó.
Đến

trong trường hợp của mẹo 3: điều gì sẽ xảy ra nếu một máy chủ memcached đi xuống và sau đó nó xuất hiện, sau đó giây máy chủ sẽ ngừng hoạt động. theo tôi hiểu - không có dữ liệu phiên nào sẽ được khôi phục và một số dữ liệu sẽ bị mất, phải không?
GioMac

28

Re: Mẹo 3 ở trên (đối với bất kỳ ai khác tình cờ gặp phải điều này qua google), có vẻ như ít nhất hiện tại để nó hoạt động, bạn phải sử dụng memcache.session_redundancy = N+1cho N máy chủ trong nhóm của mình , ít nhất đó có vẻ là ngưỡng tối thiểu giá trị mà hoạt động. (Đã thử nghiệm với php 5.3.3 trên debian ổn định, pecl memcache 3.0.6, hai máy chủ memcached. session_redundancy=2Sẽ thất bại ngay khi tôi tắt máy chủ đầu tiên trong save_path, session_redundancy=3hoạt động tốt.)

Điều này dường như được ghi lại trong các báo cáo lỗi này:


1
Không thể nâng cao bạn đủ ..
lễ hội

1
Tôi rất vui vì tôi đã cuộn xuống. Đây là vấn đề.
Daren Schwenke

Nó không rõ ràng với tôi, tính năng này chỉ có trong loạt 3.x memcache PECL phải không? Tất cả những thứ đó được liệt kê tại phần mềm Beta trên pecl.php.net/package/memcache , trong khi vào ngày 2.2.7 nếu tôi giết máy chủ mà tôi thấy nhà lãnh đạo trên thì mọi thứ đều chết.
Joe

Thành thật là nhiều năm kể từ khi tôi nhìn vào điều này, thành thật mà nói. Như tôi nhớ, đó là một tính năng 3.x (icbw). Chúng tôi đã triển khai nhiều hệ thống sử dụng các phiên bản "beta" của plugin đó (một số trong số chúng có lưu lượng truy cập khá cao) và không có bất kỳ vấn đề nào có vẻ liên quan đến điều đó. YMMV, kiểm tra mọi thứ trước khi chúng được phát hành, v.v. :) Tôi đã không làm việc trong PHP được vài năm rồi nên một số điểm nhỏ hơn của những thứ lặt vặt đang bắt đầu mờ dần.
Michael Jackson

3

Cùng với các cài đặt php.ini hiển thị ở trên, đảm bảo các cài đặt sau cũng được đặt:

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

Sau đó, bạn sẽ nhận được toàn bộ chuyển đổi dự phòng và dự phòng phía khách hàng. Thông báo trước cho cách tiếp cận này là nếu memcached bị tắt trên localhost thì sẽ luôn có lỗi đọc trước khi máy khách php memcache thử máy chủ tiếp theo trong nhóm được chỉ định trong session.save_path

Hãy nhớ rằng điều này ảnh hưởng đến các cài đặt chung cho máy khách php memcache đang chạy trên máy chủ web của bạn.


Việc sử dụng consistentchiến lược băm có hợp lý không khi xem xét sự session.save_pathkhác biệt trên mỗi máy chủ web?
Tom

1

memcached không hoạt động theo cách đó (vui lòng sửa cho tôi nếu tôi sai!)

Nếu bạn muốn ứng dụng của mình có bộ nhớ phiên dự phòng, bạn phải tạo một cái gì đó thay đổi / thêm / xóa các mục vào cả hai phiên bản memcached. memcached không xử lý việc này, điều duy nhất nó cung cấp là lưu trữ băm chính. Vì vậy, không nhân rộng, đồng bộ hóa, không có gì, nada.

Tôi hy vọng tôi không sai về vấn đề này, nhưng đây là những gì tôi biết về memcached, đã được vài năm kể từ khi tôi chạm vào nó.


Nó sẽ có ích cho tôi nếu bạn sai. :-) Có một bài viết trên phpslacker.com ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ) trong đó gợi ý memcached có thể hoạt động như được mô tả trong câu hỏi. Có lẽ nó phụ thuộc vào cách khách hàng memcache thực hiện chiến lược băm?
Tom

1
memcache không hoạt động như vậy, nhưng có vẻ như php có thể hoạt động theo cách bạn muốn. Bạn sẽ phải thay đổi php.ini hoặc thay đổi ứng dụng của bạn như được mô tả. Từ blog: Phân cụm bạn hỏi ở đâu, sự thật được nói là không có. Những gì chúng ta có cho đến nay là một nhóm memcache bao gồm 2 máy chủ. PHP được cấu hình để ghi vào nhóm. PHP đọc / ghi vào nhóm máy chủ theo thứ tự được chỉ định bởi chỉ thị phiên session.save_path. Để đọc PHP sẽ yêu cầu một đối tượng bộ đệm theo khóa từ nhóm. Bởi vì, failover, được bật, PHP sẽ truy vấn từng nhóm máy chủ memcache cho đến khi [...]
xé-

1

memcached không sao chép ra khỏi hộp, nhưng repcached (một bản vá đã được vá) thì không. Tuy nhiên, nếu bạn đã sử dụng mysql thì tại sao không sử dụng chức năng sao chép của nó với sao chép chính chủ và nhận được lợi ích của sao chép dữ liệu đầy đủ.

C.


Cảm ơn bạn về thông tin. Nó không thực sự là bản sao mà tôi đang theo đuổi. Đó là nhiều hơn một trường hợp muốn lần lượt đạt đến đỉnh memcached cho đến khi phiên được tìm thấy. tức là kiểm tra localhost trước vì nó nhanh nhất và sau đó kiểm tra máy chủ khác tiếp theo.
Tom

1
Nhân danh tất cả các vị thần TẠI SAO ???? Đây là giải pháp hoàn toàn sai lầm cho .... cũng chỉ về bất kỳ vấn đề nào tôi có thể nghĩ ra. Ngoài việc rất kém hiệu quả, chỉ với 2 máy chủ, hiệu suất sẽ ngày càng tệ đi rất nhanh nếu bạn thêm nhiều máy chủ. Và điều đó không xem xét đến thực tế là giải pháp của bạn khiến mất điện gấp đôi so với một máy chủ khi thực tế việc thêm máy chủ vào một cụm sẽ làm giảm khả năng ngừng hoạt động. (BTW nếu bạn có nghĩa là vòng tròn dựa trên DNS thì mối quan hệ phiên là ẩn!)
symcbean

Cảm ơn đã phản hồi, vâng, tôi thoải mái thừa nhận tôi là người không biết chia sẻ phiên! :-) Tuy nhiên, tôi vẫn chưa hiểu tại sao đề xuất của mình quá xấu. Tôi nghĩ rằng nó sẽ hiệu quả hơn so với việc sử dụng DB được chia sẻ và tôi cũng nghĩ rằng nó sẽ khiến việc ngừng hoạt động ít xảy ra hơn.
Tom

Không, nó làm cho họ có nhiều khả năng. Liên kết dữ liệu như thế này có ý nghĩa khi bạn có số lượng nút rất lớn vì bạn giảm số lượng sao chép nhưng người ta thường thực hiện một số lần sao chép mà không có số lượng nhóm xác định để duy trì tính khả dụng. Bạn cần phải rất kén chọn về hiệu suất để thấy sự khác biệt giữa sao chép được lặp lại và sao chép mysqld.
symcbean

Tôi đã kiểm tra và xác nhận rằng miễn là tôi đang sử dụng allow_failover = 1, nhiều gương sẽ khiến mất điện LESS. Tôi có thể tắt một gương, khởi động lại và tắt máy kia, khởi động lại và tắt lần đầu tiên - tất cả mà không bị đăng xuất. Tôi đoán rằng máy khách memcache PHP đang thực hiện rất nhiều mánh khóe đằng sau hậu trường.
Tom
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.