stringtranslate.com

Memcached

Memcached (pronunciado de diversas formas mem-cash-dee o mem-cashed ) es un sistema de almacenamiento en caché de memoria distribuido de propósito general . A menudo se utiliza para acelerar los sitios web dinámicos basados ​​en bases de datos mediante el almacenamiento en caché de datos y objetos en la RAM para reducir la cantidad de veces que se debe leer una fuente de datos externa (como una base de datos o API). Memcached es un software gratuito y de código abierto , con licencia BSD revisada . [2] Memcached se ejecuta en sistemas operativos tipo Unix ( Linux y macOS ) y en Microsoft Windows . Depende de la biblioteca libevent .

Las API de Memcached proporcionan una tabla hash muy grande distribuida en varias máquinas. Cuando la tabla está llena, las inserciones posteriores hacen que los datos más antiguos se eliminen en el orden de los menos utilizados recientemente (LRU). [3] [4] Las aplicaciones que utilizan Memcached suelen colocar las solicitudes y las adiciones en la RAM antes de recurrir a un almacenamiento de respaldo más lento, como una base de datos.

Memcached no tiene ningún mecanismo interno para realizar un seguimiento de los errores que puedan ocurrir. Sin embargo, algunas utilidades de terceros ofrecen esta funcionalidad.

Memcached fue desarrollado por primera vez por Brad Fitzpatrick para su sitio web LiveJournal , el 22 de mayo de 2003. [5] [6] Originalmente fue escrito en Perl , luego reescrito en C por Anatoly Vorobey, luego empleado por LiveJournal. [7] Memcached ahora es utilizado por muchos otros sistemas, incluidos YouTube , [8] Reddit , [9] Facebook , [10] [11] Pinterest , [12] [13] Twitter , [14] Wikipedia , [15] y Method Studios . [16] Google App Engine , Google Cloud Platform , Microsoft Azure , IBM Bluemix y Amazon Web Services también ofrecen un servicio Memcached a través de una API. [17] [18] [19] [20]

Arquitectura de software

El sistema utiliza una arquitectura cliente-servidor . Los servidores mantienen una matriz asociativa de clave-valor ; los clientes llenan esta matriz y la consultan por clave. Las claves tienen una longitud de hasta 250 bytes y los valores pueden tener un tamaño máximo de 1 megabyte .

Los clientes utilizan bibliotecas del lado del cliente para contactar con los servidores que, de manera predeterminada, exponen su servicio en el puerto 11211. Se admiten tanto TCP como UDP. Cada cliente conoce todos los servidores; los servidores no se comunican entre sí. Si un cliente desea establecer o leer el valor correspondiente a una clave determinada, la biblioteca del cliente primero calcula un hash de la clave para determinar qué servidor utilizar. Esto proporciona una forma simple de fragmentación y una arquitectura escalable de no compartir nada entre los servidores. El servidor calcula un segundo hash de la clave para determinar dónde almacenar o leer el valor correspondiente. Los servidores mantienen los valores en la RAM; si un servidor se queda sin RAM, descarta los valores más antiguos. Por lo tanto, los clientes deben tratar Memcached como un caché transitorio; no pueden asumir que los datos almacenados en Memcached todavía están allí cuando los necesitan. Otras bases de datos, como MemcacheDB , Couchbase Server , proporcionan almacenamiento persistente al tiempo que mantienen la compatibilidad del protocolo Memcached.

Si todas las bibliotecas cliente utilizan el mismo algoritmo hash para determinar servidores, entonces los clientes pueden leer los datos almacenados en caché de los demás.

Una implementación típica tiene varios servidores y muchos clientes. Sin embargo, es posible utilizar Memcached en una sola computadora, actuando simultáneamente como cliente y servidor. El tamaño de su tabla hash suele ser muy grande. Está limitada a la memoria disponible en todos los servidores del clúster de servidores de un centro de datos. Cuando lo requiere la publicación web de gran volumen y para una amplia audiencia, esta capacidad puede llegar a muchos gigabytes. Memcached puede ser igualmente valioso para situaciones en las que la cantidad de solicitudes de contenido es alta o el costo de generar un contenido en particular es alto.

Seguridad

La mayoría de las implementaciones de Memcached se realizan en redes confiables donde los clientes pueden conectarse libremente a cualquier servidor. Sin embargo, a veces Memcached se implementa en redes que no son confiables o donde los administradores desean ejercer control sobre los clientes que se conectan. Para este propósito, Memcached se puede compilar con soporte de autenticación SASL opcional . El soporte SASL requiere el protocolo binario.

Una presentación en BlackHat USA 2010 reveló que varios sitios web públicos grandes habían dejado Memcached abierto a la inspección, análisis, recuperación y modificación de datos. [21]

Incluso dentro de una organización confiable, el modelo de confianza plana de Memcached puede tener implicaciones de seguridad. Para simplificar, todas las operaciones de Memcached se tratan por igual. Los clientes con una necesidad válida de acceso a entradas de baja seguridad dentro de la caché obtienen acceso a todas las entradas dentro de la caché, incluso cuando estas son de mayor seguridad y ese cliente no tiene una necesidad justificable de ellas. Si la clave de la caché se puede predecir, adivinar o encontrar mediante una búsqueda exhaustiva, se puede recuperar su entrada de caché.

En situaciones como la publicación web de gran volumen, se pueden hacer algunos intentos de aislar los datos de configuración y lectura. Una granja de servidores de contenido orientados al exterior tiene acceso de lectura a memcached que contiene páginas publicadas o componentes de página, pero no acceso de escritura. Cuando se publica contenido nuevo (y aún no está en memcached), se envía una solicitud a los servidores de generación de contenido que no son de acceso público para crear la unidad de contenido y agregarla a memcached. Luego, el servidor de contenido vuelve a intentar recuperarla y enviarla al exterior.

Utilizado como vector de ataque DDoS

En febrero de 2018, CloudFlare informó que se utilizaron servidores memcached mal configurados para lanzar ataques DDoS a gran escala. [22] El protocolo memcached sobre UDP tiene un enorme factor de amplificación , de más de 51000. [23] Entre las víctimas de los ataques DDoS se incluye GitHub , que se inundó con un tráfico entrante máximo de 1,35 Tbit/s. [24]

Este problema se mitigó en la versión 1.5.6 de Memcached, que deshabilitó el protocolo UDP de forma predeterminada. [25]

Código de ejemplo

Tenga en cuenta que todas las funciones descritas en esta página son solo pseudocódigo . Las llamadas a Memcached y los lenguajes de programación pueden variar según la API utilizada.

La conversión de consultas de creación de objetos o bases de datos para utilizar Memcached es sencilla. Normalmente, cuando se utilizan consultas de base de datos directas, el código de ejemplo sería el siguiente:

 función get_foo ( int id_usuario ) datos = db_select ( "SELECT * FROM users WHERE id_usuario = ?" , id_usuario ) devolver datos        

Después de la conversión a Memcached, la misma llamada podría verse así:

 función get_foo ( int userid ) /* primero prueba el caché */ datos = memcached_fetch ( "userrow:" + userid ) si no datos /* no encontrado: solicitud a la base de datos */ datos = db_select ( "SELECT * FROM users WHERE userid = ?" , userid ) /* luego almacena en caché hasta la próxima obtención */ memcached_add ( "userrow:" + userid , datos ) fin                       devolver datos 

El cliente primero verificaría si existe un valor de Memcached con la clave única "userrow:userid", donde userid es un número. Si el resultado no existe, seleccionaría de la base de datos como de costumbre y establecería la clave única mediante la llamada a la función add de la API de Memcached.

Sin embargo, si solo se modificara esta llamada API, el servidor terminaría obteniendo datos incorrectos después de cualquier acción de actualización de la base de datos: la "vista" de los datos de Memcached quedaría obsoleta. Por lo tanto, además de crear una llamada "add", también sería necesaria una llamada update utilizando la función set de Memcached.

 function update_foo ( int userid , string dbUpdateString ) /* primera actualización de la base de datos */ result = db_execute ( dbUpdateString ) if result /* actualización de la base de datos exitosa: obtener los datos que se almacenarán en la memoria caché */ data = db_select ( "SELECT * FROM users WHERE userid = ?" , userid ) /* la línea anterior también podría verse así data = createDataFromDBString(dbUpdateString) */ /* luego almacenar en la memoria caché hasta la próxima obtención */ memcached_set ( "userrow:" + userid , data )                     

Esta llamada actualizaría los datos almacenados actualmente en caché para que coincidan con los nuevos datos en la base de datos, suponiendo que la consulta de la base de datos tenga éxito. Un enfoque alternativo sería invalidar la caché con la función de eliminación de Memcached, de modo que las recuperaciones posteriores generen un error de caché. Sería necesario tomar una acción similar cuando se eliminaran registros de la base de datos, para mantener una caché correcta o incompleta.

Una estrategia alternativa de invalidación de caché es almacenar un número aleatorio en una entrada de caché acordada e incorporar este número en todas las claves que se utilizan para almacenar un tipo particular de entrada. Para invalidar todas esas entradas a la vez, cambie el número aleatorio. Las entradas existentes (que se almacenaron utilizando el número anterior) ya no serán referenciadas y, por lo tanto, eventualmente caducarán o serán recicladas.

 function store_xyz_entry ( int key , string value ) /* Recuperar el número aleatorio - usar cero si no existe ninguno todavía.  * El nombre de clave usado aquí es arbitrario. */ seed = memcached_fetch ( ":xyz_seed:" ) if not seed seed = 0 /* Construir la clave usada para almacenar la entrada y almacenarla.  * El nombre de clave usado aquí también es arbitrario. Observe que la "semilla" y la "clave" del usuario  * se almacenan como partes separadas de la cadena hashKey construida: ":xyz_data:(seed):(key)."  * Esto no es obligatorio, pero se recomienda. */ string hashKey = sprintf ( ":xyz_data:%d:%d" , seed , key ) memcached_set ( hashKey , value )                         /* "fetch_entry", no se muestra, sigue una lógica idéntica a la anterior. */ function invalidate_xyz_cache () existing_seed = memcached_fetch ( ":xyz_seed:" ) /* Acuñar una semilla aleatoria diferente */ do seed = rand () till seed != existing_seed /* Ahora almacenarla en el lugar acordado. Todas las solicitudes futuras usarán este número.  * Por lo tanto, todas las entradas existentes dejan de tener referencias y eventualmente expirarán. */ memcached_set ( ":xyz_seed:" , seed )                

Uso

Véase también

Referencias

  1. ^ "Versión 1.6.31". 7 de septiembre de 2024. Consultado el 22 de septiembre de 2024 .
  2. ^ ab "Licencia de Memcached". GitHub . Consultado el 27 de junio de 2014 .
  3. ^ "Archivo de código de Google: almacenamiento a largo plazo para el alojamiento de proyectos de código de Google". Code.google.com . Consultado el 25 de junio de 2017 .
  4. ^ "Archivo de código de Google: almacenamiento a largo plazo para el alojamiento de proyectos de código de Google". Code.google.com . Consultado el 25 de junio de 2017 .
  5. ^ [1]. Community.livejournal.com (22 de mayo de 2003). Recuperado el 18 de septiembre de 2013.
  6. ^ [2]. Community.livejournal.com (27 de mayo de 2003). Recuperado el 18 de septiembre de 2013.
  7. ^ "lj_dev: memcached". 25 de febrero de 2013. Archivado desde el original el 25 de febrero de 2013. Consultado el 25 de junio de 2017 .
  8. ^ Cuong Do Cuong (director de ingeniería de YouTube/Google) (23 de junio de 2007). Conferencia de Seattle sobre escalabilidad: escalabilidad de YouTube (video en línea, minuto 26). Seattle: Google Tech Talks.
  9. ^ Whitaker, Keir (17 de mayo de 2010). "Steve Huffman habla de las lecciones aprendidas en Reddit | Carsonified". Archivado desde el original el 17 de mayo de 2010. Consultado el 25 de junio de 2017 .
  10. ^ "Escalamiento de memcached en Facebook". Facebook.com . 2008-12-12 . Consultado el 2017-06-25 .
  11. ^ Escalado de Memcache en Facebook. USENIX. 2002. ISBN 9781931971003. Recuperado el 25 de junio de 2017 .
  12. ^ "Construyendo Pinterest en la nube". Carreras en Pinterest . 2013-06-19 . Consultado el 2018-03-09 .
  13. ^ "Un cliente de caché en memoria completo, rápido y puro para Python". Github.com . 2018-01-08 . Consultado el 2018-03-09 .
  14. ^ "No es ciencia espacial, pero es nuestro trabajo". Blog.twitter.com . 2008-06-01 . Consultado el 2017-06-25 .
  15. ^ "memorizado en caché". MediosWiki . Consultado el 25 de junio de 2017 .
  16. ^ Rez BoF, SIGGRAPH 2019, archivado desde el original el 12 de diciembre de 2021 , consultado el 9 de agosto de 2019
  17. ^ "Ejemplos de Memcache | Entorno estándar de App Engine para Python | Google Cloud Platform". Code.google.com . 2017-03-22 . Consultado el 2017-06-25 .
  18. ^ "Acerca de la caché en función para Azure Cache". Msdn.microsoft.com . 2015-08-25 . Consultado el 2017-06-25 .
  19. ^ Verge, Jason (23 de septiembre de 2014). "Redis Labs: tenemos 3000 clientes que pagan por el servicio NoSQL en la nube". Data Center Knowledge . Consultado el 10 de septiembre de 2016 .
  20. ^ "AWS | Amazon ElastiCache: almacenamiento de datos en memoria y caché". Aws.amazon.com . Consultado el 25 de junio de 2017 .
  21. ^ "SensePost | Artículo de Blackhat: Go-derper y la minería de memcaches". Archivado desde el original el 21 de diciembre de 2018. Consultado el 2 de septiembre de 2016 .
  22. ^ "Memcrashed - Ataques de amplificación importantes desde el puerto UDP 11211". CloudFlare. 27 de febrero de 2018. Consultado el 3 de marzo de 2018 .
  23. ^ Jeffrey, Cal (1 de marzo de 2018). "GitHub es víctima del mayor ataque DDoS jamás registrado".
  24. ^ "Informe del incidente DDoS del 28 de febrero". 1 de marzo de 2018. Consultado el 3 de marzo de 2018 .
  25. ^ "Notas de la versión 1.5.6 de Memcached". GitHub . 2018-02-27 . Consultado el 3 de marzo de 2018 .
  26. ^ "Speedy MySQL 5.6 apunta a NoSQL y MariaDB". Theregister.co.uk . Consultado el 25 de junio de 2017 .
  27. ^ David Felcey (13 de agosto de 2014). "Introducción al adaptador Coherence Memcached | Blog de Oracle Coherence". Blogs.oracle.com . Archivado desde el original el 23 de febrero de 2017. Consultado el 25 de junio de 2017 .
  28. ^ "Uso del punto final del protocolo Memcached con Infinispan". infinispan.org . Consultado el 19 de abril de 2022 .

Enlaces externos