¿Se puede usar un grupo de demonios memcache para compartir sesiones de manera más eficiente?

25

Estamos pasando de una configuración de 1 servidor web a una configuración de dos servidores web y necesito comenzar a compartir sesiones PHP entre las dos máquinas con equilibrio de carga. Ya hemos instalado memcached ( y empezamos ) y, por lo tanto, me sorprendió gratamente que pudiera lograr compartir sesiones entre los nuevos servidores cambiando solo 3 líneas en el php.iniarchivo ( session.save_handler y session.save_path ):

Reemplacé:

session.save_handler = files

con:

session.save_handler = memcache

Luego, en el servidor web maestro, configuré session.save_pathpara que apunte a localhost:

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

y en el servidor web esclavo configuré session.save_pathpara que apunte al maestro:

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

Trabajo hecho, lo probé y funciona. Pero...

Obviamente, usar memcache significa que las sesiones están en RAM y se perderán si se reinicia una máquina o el demonio memcache se bloquea: estoy un poco preocupado por esto, pero estoy un poco más preocupado por el tráfico de red entre los dos servidores web (especialmente porque escalamos) porque cada vez que alguien tiene una carga equilibrada en el servidor web esclavo, sus sesiones se recuperarán a través de la red desde el servidor web maestro. Me preguntaba si podría definir dos save_pathspara que las máquinas busquen en su propio almacenamiento de sesión antes de usar la red. Por ejemplo:

Dominar:

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

Esclavo:

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

¿Compartiría con éxito las sesiones entre los servidores Y ayudaría al rendimiento? es decir, ahorrar tráfico de red el 50% del tiempo. ¿O es esta técnica solo para failovers (por ejemplo, cuando un demonio memcache no está disponible)?

Nota : Realmente no estoy preguntando específicamente sobre la replicación de Memcache, más acerca de si el cliente PHP Memcache puede alcanzar el máximo dentro de cada demonio Memcache en un grupo, devolver una sesión si encuentra una y solo crear una nueva sesión si no encuentra una En todas las tiendas. Mientras escribo esto, creo que estoy pidiendo un poco de PHP, jajaja ...

Suponga : sin sesiones fijas, balanceo de carga round-robin, servidores LAMP

Tom
fuente
1
La documentación de Memcache no recomienda usar Memcache para el almacenamiento de la sesión. Ver code.google.com/p/memcached/wiki/… !

Respuestas:

37

Descargo de responsabilidad: te enojaría escucharme sin hacer una tonelada de pruebas Y obtener una segunda opinión de alguien calificado: soy nuevo en este juego .

La idea de mejora de eficiencia propuesta en esta pregunta no funcionará. El principal error que cometí fue pensar que el orden en que se definen los almacenes de memoria caché en el grupo dicta algún tipo de prioridad. Este no es el caso . Cuando define un grupo de demonios combinados (por ejemplo, usando session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"), no puede saber qué tienda se usará. Los datos se distribuyen de manera uniforme, lo que significa que un elemento podría almacenarse en el primero, o podría ser el último (o podría ser ambos si el cliente memcache está configurado para replicarse; tenga en cuenta que es el cliente que maneja la replicación, el servidor memcached lo hace). no hacerlo por sí mismo). De cualquier manera significará que usar localhost como el primero en el grupo no mejorará el rendimiento: hay un 50% de posibilidades de llegar a cualquiera de las tiendas.

Después de haber hecho un poco de pruebas e investigaciones, he concluido que PUEDES compartir sesiones entre servidores usando Memcache PERO probablemente no quieras, no parece ser popular porque no se escala tan bien como el uso compartido la base de datos no es tan robusta. Agradecería comentarios sobre esto para poder aprender más ...

Ignora lo siguiente a menos que tengas una aplicación PHP:


Consejo 1: si desea compartir sesiones en 2 servidores usando memcache:

Asegúrese de haber respondido a "¿ Habilitar la compatibilidad con el controlador de sesión de memcache? " Cuando instaló el cliente PHP memcache y agregue lo siguiente en su /etc/php.d/memcache.iniarchivo:

session.save_handler = memcache

En el servidor web 1 (IP: 192.168.0.1):

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

En el servidor web 2 (IP: 192.168.0.2):

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

Consejo 2: si desea compartir sesiones en 2 servidores utilizando memcache Y tener soporte de conmutación por error:

Agregue lo siguiente a su /etc/php.d/memcache.iniarchivo:

memcache.hash_strategy = consistent
memcache.allow_failover = 1

En el servidor web 1 (IP: 192.168.0.1):

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

En el servidor web 2 (IP: 192.168.0.2):

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

Notas:

  • Esto resalta otro error que cometí en la pregunta original: no estaba usando una idéntica session.save_pathen todos los servidores.
  • En este caso, "failover" significa que si un demonio memcache falla, el cliente PHP memcache comenzará a usar el otro. es decir, cualquier persona que tuvo su sesión en la tienda que falló se cerrará sesión. No es una conmutación por error transparente.

Consejo 3: si desea compartir sesiones usando memcache Y tener soporte transparente de conmutación por error:

Igual que el consejo 2, excepto que necesita agregar lo siguiente a su /etc/php.d/memcache.iniarchivo:

memcache.session_redundancy=2

Notas:

  • Esto hace que el cliente PHP memcache escriba las sesiones en 2 servidores. Obtiene redundancia (como RAID-1) de modo que las escrituras se envían a n mirrors y fallaget's se vuelvan a intentar en los espejos. Esto significará que los usuarios no perderán su sesión en el caso de una falla del demonio memcache.
  • Las escrituras duplicadas se realizan en paralelo (usando IO sin bloqueo) para que el rendimiento de la velocidad no disminuya mucho a medida que aumenta el número de réplicas. Sin embargo, el tráfico de red aumentará si sus duplicados de memcache se distribuyen en diferentes máquinas. Por ejemplo, ya no hay un 50% de posibilidades de usar localhost y evitar el acceso a la red.
    • Aparentemente, la demora en la replicación de escritura puede hacer que se recuperen datos antiguos en lugar de una pérdida de caché. La pregunta es si esto es importante para su aplicación. ¿Con qué frecuencia escribe datos de sesión?
  • memcache.session_redundancy es para redundancia de sesión pero también hay un memcache.redundancy opción ini que puede ser utilizada por el código de su aplicación PHP si desea que tenga un nivel diferente de redundancia.
  • Necesita una versión reciente (todavía en beta en este momento) del cliente PHP memcache: la versión 3.0.3 de pecl funcionó para mí.
Tom
fuente
¿Podría comentar sobre "no escala tan bien como usar una base de datos compartida"? No veo cómo es diferente de una configuración típica de DB maestro-esclavo. ¡Gracias!
Boy Baukema
Este es un desglose bastante bueno, aunque hay rumores (también conocidos como informes de errores) de que esto no funciona como se esperaba cuando usa la ext/memcacheversión 3.x. También estamos jugando con esa opción y decidí recorrer la lista de servidores y escribirla yo mismo.
Hasta el
en el caso de la sugerencia 3: ¿qué pasa si un host memcached se cae y luego sube, luego el host se cae? Según tengo entendido, no se restaurarán los datos de la sesión y algunos se perderán, ¿verdad?
GioMac
28

Re: Consejo 3 anterior (para cualquier otra persona que se encuentre con esto a través de Google), parece que al menos actualmente para que esto funcione debe usar memcache.session_redundancy = N+1N servidores en su grupo , al menos ese parece ser el umbral mínimo valor que funciona. (Probado con php 5.3.3 en Debian estable, pecl memcache 3.0.6, dos servidores memcached. Fallaría session_redundancy=2tan pronto como apague el primer servidor en el save_path, session_redundancy=3funciona bien).

Esto parece ser capturado en estos informes de errores:

Michael Jackson
fuente
1
No puedo votarte lo suficiente ..
fest
1
Me alegro de haberme desplazado hacia abajo. Este fue el problema.
Daren Schwenke
No me queda claro, ¿esta función solo está disponible en la serie PECL memcache 3.x? Todos estos están listados en el software Beta en pecl.php.net/package/memcache , mientras que en 2.2.7 si elimino el servidor en el que veo al líder, todo muere.
Joe
Han pasado años desde que vi esto, para ser honesto. Según recuerdo, era una característica 3.x (icbw). Implementamos muchos sistemas usando las versiones "beta" de ese complemento (algunos de ellos con mucho tráfico) y no tuvimos ningún problema que pareciera relacionado con eso. YMMV, prueba cosas antes de que se publiquen, etc. :) No he estado trabajando en PHP durante algunos años, por lo que algunos de los puntos más delicados de la trivia comienzan a desvanecerse.
Michael Jackson
3

Junto con la configuración de php.ini que se muestra arriba, asegúrese de que también se configure lo siguiente:

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

Entonces obtendrá una conmutación por error completa y redundancia del lado del cliente. La advertencia con este enfoque es que si memcached está inactivo en localhost siempre habrá una falta de lectura antes de que el cliente php memcache intente el siguiente servidor en el grupo especificado en session.save_path

Solo tenga en cuenta que esto afecta la configuración global del cliente php memcache que se ejecuta en su servidor web.

Ian Lewis
fuente
¿Tiene sentido usar una consistentestrategia de hashing teniendo en cuenta que session.save_pathes diferente en cada servidor web?
Tom
1

memcached no funciona de esa manera (¡corrígeme si me equivoco!)

Si desea que su aplicación tenga almacenamiento de sesión redundante, debe crear algo que altere / agregue / elimine entradas en ambas instancias de memoria caché. memcached no maneja esto, lo único que proporciona es como almacenamiento de hash clave. Entonces no hay replicación, sincronización, nada, nada.

Espero no estar equivocado en este asunto, pero esto es lo que sé de memcached, han pasado algunos años desde que lo toqué.

rasgó
fuente
Sería útil para mí si te equivocases. :-) Hay un artículo en phpslacker.com ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ) que sugiere que memcached puede funcionar como se describe en la pregunta. ¿Quizás depende de cómo el cliente memcache implementa la estrategia de hash?
Tom
1
memcache no funciona así, pero parece que php puede funcionar de la manera que lo desee. Tendrá que cambiar php.ini o cambiar su aplicación como se describe. Del blog: ¿Dónde está la agrupación que preguntas? Bueno, la verdad sea dicha, no hay ninguna. Lo que tenemos hasta ahora es un grupo de memcache que consta de 2 servidores. PHP está configurado para escribir en el grupo. PHP lee / escribe en el grupo de servidores en el orden especificado por la directiva ini "session.save_path". Para las lecturas, PHP solicitará un objeto de caché por clave del grupo. Debido a que la "conmutación por error" está habilitada, PHP consultará el grupo de servidores de Memcache uno por uno hasta el [...]
tore-
1

memcached no se replica fuera de la caja, pero lo hace repcached (un memcached parcheado). Sin embargo, si ya está utilizando mysql, ¿por qué no usar su funcionalidad de replicación con la replicación maestro-maestro y obtener el beneficio de la replicación de datos completa?

DO.

symcbean
fuente
Gracias por la info. No es realmente la replicación lo que busco. Es más un caso de querer alcanzar el máximo en cada memcached a su vez hasta que se encuentre la sesión. es decir, comprobar localhost primero porque es más rápido y luego verificar el otro servidor a continuación.
Tom
1
En nombre de todos los dioses ¿POR QUÉ ???? Esta es la solución totalmente incorrecta para ... bueno, casi cualquier problema que se me ocurra. Además de ser muy ineficiente, incluso con solo 2 servidores, el rendimiento empeorará progresivamente muy rápidamente si alguna vez agrega más servidores. Y eso no tiene en cuenta el hecho de que su solución hace que las interrupciones sean dos veces más probables que con un solo servidor cuando, en la práctica, agregar servidores a un clúster debería reducir la probabilidad de una interrupción. (Round-robin Por cierto si usted basado DNS media entonces la afinidad de sesiones está implícito!)
symcbean
Gracias por los comentarios, sí, ¡admito que soy un novato en el intercambio de sesiones! :-) Sin embargo, todavía no entiendo por qué mi propuesta es tan fea. Pensé que sería más eficiente que usar una base de datos compartida y también pensé que haría menos probable las interrupciones.
Tom
No, los hace más probables. Federando los datos de esta manera tiene sentido cuando tiene un número muy grande de nodos porque reduce la cantidad de replicación, pero uno típicamente haría alguna replicación dentro de un número definido de grupos para preservar la disponibilidad. Tendría que ser muy exigente con el rendimiento para ver la diferencia entre la replicación reprogramada y la replicación mysqld.
symcbean
He probado y confirmado que mientras esté usando allow_failover = 1, múltiples espejos hacen que las interrupciones sean MENOS probables. Puedo apagar un espejo, reiniciarlo y apagar el otro, reiniciarlo y apagar el primero nuevamente, todo sin cerrar sesión. Supongo que el cliente PHP Memcache está haciendo muchos trucos detrás de escena.
Tom