2008-11-04 10 views
8

Versión corta¿Buscar en fragmentos?

Si se separaron mis usuarios en fragmentos, ¿cómo puedo ofrecer una "búsqueda de usuario"? Obviamente, no quiero que todas las búsquedas lleguen a todos los fragmentos.

versión larga

Por fragmento, quiero decir tiene múltiples bases de datos, donde cada uno contiene una fracción de los datos totales. Para un ejemplo (ingenuo), las bases de datos UserA, UserB, etc. pueden contener usuarios cuyos nombres comiencen con "A", "B", etc. Cuando un nuevo usuario se registra, simplemente examino su nombre y lo coloco en el correcto base de datos. Cuando un usuario que regresa inicia sesión, vuelvo a mirar su nombre para determinar la base de datos correcta de donde extraerá su información.

La ventaja de sharding vs read replication es que la replicación de lectura no escala sus escrituras. Todas las escrituras que van al maestro tienen que ir a cada esclavo. En cierto sentido, todos llevan la misma carga de escritura, a pesar de que la carga de lectura se distribuye.

Mientras tanto, a los fragmentos no les importan las escrituras de los demás. Si Brian se registra en el fragmento de UserB, el fragmento de UserA no necesita saber al respecto. Si Brian envía un mensaje a Alex, puedo registrar ese hecho en los fragmentos UserA y UserB. De esta forma, cuando Alex o Brian inician sesión, puede recuperar todos sus mensajes enviados y recibidos desde su propio fragmento sin consultar todos los fragmentos.

Hasta ahora, todo bien. ¿Qué hay de las búsquedas? En este ejemplo, si Brian busca "Alex", puedo marcar UserA. Pero, ¿y si busca a Alex por su apellido, "Smith"? Hay Smith en todos los fragmentos. Desde aquí, veo dos opciones:

  1. Haga que la aplicación busque Smiths en cada fragmento. Esto se puede hacer lentamente (consultar cada fragmento en sucesión) o rápidamente (consultar cada fragmento en paralelo), pero de cualquier forma, cada fragmento debe estar involucrado en cada búsqueda. De la misma manera que la replicación de lectura no escala las escrituras, hacer que las búsquedas accedan a cada fragmento no escala sus búsquedas. Puede llegar a un momento en que el volumen de búsqueda sea lo suficientemente alto como para abrumar a cada fragmento, y agregar fragmentos no lo ayuda, ya que todos obtienen el mismo volumen.
  2. Algún tipo de indización que en sí es tolerante a la fragmentación. Por ejemplo, digamos que tengo un número constante de campos por los cuales quiero buscar: nombre y apellido. Además de UserA, UserB, etc. También tengo IndexA, IndexB, etc. Cuando un nuevo usuario se registra, lo adjunto a cada índice en el que quiero que se encuentre. Así que puse a Alex Smith en IndexA e IndexS, y se lo puede encontrar en "Alex" o "Smith", pero no en las subcadenas. De esta forma, no necesita consultar cada fragmento, por lo que la búsqueda puede ser escalable.

Entonces, ¿se puede escalar la búsqueda? Si es así, ¿este enfoque de indexación es el correcto? Hay alguna otra?

Respuesta

2

Te estoy asumiendo que están hablando de fragmentos a la: http://highscalability.com/unorthodox-approach-database-design-coming-shard

Si usted lee este artículo que entra en algunos detalles sobre exactamente su pregunta, pero la respuesta a corto, se escribe código de aplicaciones personalizadas para llevar su fragmentos dispares juntos. Puede hacer un hash inteligente para consultar fragmentos individuales e insertar datos en fragmentos. Necesitas hacer una pregunta más específica para obtener una respuesta más específica.

+0

Gracias. De hecho, he leído ese sitio extensivamente. Intenté aclarar mi pregunta anterior; lo cual, con suerte, va más allá del artículo que vinculaste de manera útil. –

1

Realmente necesita que todas las búsquedas accedan a cada fragmento, o al menos todas las búsquedas deben realizarse contra un índice que contiene los datos de todos los fragmentos, que se reduce a lo mismo.

Presumiblemente usted fragmento basado en una sola propiedad del usuario, probablemente un hash del nombre de usuario. Si su función de búsqueda permite al usuario buscar en base a otras propiedades del usuario, está claro que no existe un solo fragmento o subconjunto de fragmentos que puedan satisfacer una consulta, ya que cualquier fragmento podría contener usuarios que coincidan con la consulta. No puede descartar ningún fragmento antes de realizar la búsqueda, lo que implica que debe ejecutar la consulta contra todos los fragmentos.

+0

Por favor vea mi aclaración arriba. –

7

No hay una bala mágica.

La búsqueda de cada fragmento en sucesión está fuera de cuestión, obviamente, debido a la latencia increíblemente alta en la que incurrirá.

Así que desea buscar en paralelo, si es necesario.

Hay dos opciones realistas, y usted ya las enlistó: indexación y búsqueda paralelizada. Permítanme entrar un poco más en detalle sobre cómo diseñarlos.

La idea clave que puede utilizar es que en la búsqueda, rara vez necesita el conjunto completo de resultados. Solo necesita la primera (o enésima) página de resultados. Así que hay bastante margen de maniobra que puede usar para disminuir el tiempo de respuesta.

Indexación

Si conoce los atributos sobre los que se buscarán los usuarios, puede crear costumbre, índices separados para ellos. Puede crear su propio inverted index, que apuntará a la tupla (shard, recordId) para cada término de búsqueda, o puede almacenarlo en la base de datos. Actualízalo de forma perezosa y de forma asíncrona. No conozco los requisitos de su aplicación, incluso podría ser posible reconstruir el índice todas las noches (lo que significa que no tendrá las entradas más recientes en un día determinado, pero eso podría estar bien para usted). Asegúrese de optimizar este índice por tamaño para que pueda caber en la memoria; tenga en cuenta que puede copiar este índice, si es necesario.

Naturalmente, si las personas pueden buscar algo como "lastname='Smith' OR lastname='Jones'", puede leer el índice de Smith, leer el índice de Jones y calcular la unión; no es necesario almacenar todas las consultas posibles, solo sus partes de construcción.

paralelo Buscar

Para cada consulta, enviar peticiones a cada fragmento a menos que sepa lo que debe buscar fragmento porque la búsqueda pasa a estar en la clave de distribución. Haga las solicitudes asincrónicas. Responda al usuario tan pronto como obtenga los resultados de la primera página; recopile el resto y el caché localmente, de modo que si el usuario marca "siguiente" tendrá los resultados listos y no necesita volver a consultar los servidores. De esta forma, si algunos de los servidores tardan más tiempo que otros, no es necesario que espere para atender la solicitud.

Mientras tanto, registre los tiempos de respuesta de los servidores fragmentados para observar problemas potenciales con datos desiguales y/o distribución de carga.

1

Es posible que desee mirar Sphinx (http://www.sphinxsearch.com/articles.html). Es compatible con la búsqueda distribuida. GigaSpaces tiene soporte de consultas y fusiones paralelas. Esto también se puede hacer con MySQL Proxy (http://jan.kneschke.de/2008/6/2/mysql-proxy-merging-resultsets).

Para construir un tipo indexado no fragmentado de derrotas el propósito del fragmento en primer lugar :-) Un índice centralizado probablemente no funcionará si los fragmentos fueran necesarios.

Creo que todos los fragmentos deben ser golpeados en paralelo.Los resultados deben ser filtrados, clasificados, ordenados, agrupados y los resultados fusionados de todos los fragmentos. Si los fragmentos se vuelven abrumados, tienes que hacer lo habitual (reshard, ampliar, etc.) para abatirlos de nuevo.

0

Las RDBM no son una buena herramienta para la búsqueda de texto. Estará mucho mejor mirando Solr. La diferencia de rendimiento entre Solr y la base de datos será del orden de magnitud de 100X.

Cuestiones relacionadas