tutorial template sheet linebreaksbr dirs cheat django postgresql sharding instagram

sheet - load django template



Haciendo sharding simple con Django (2)

Mike Clarke recientemente dio una charla en PyPgDay sobre cómo Disqus desecha a sus usuarios con Django y PostgreSQL. Escribió una publicación en el blog sobre cómo lo hacen.

Se pueden emplear varias estrategias al fragmentar las bases de datos de Postgres. En Disqus, elegimos fragmentar según el nombre de la tabla. Donde el nombre de la tabla original generado por Django podría ser comments_post, nuestras herramientas de fragmentación volverán a escribir el SQL para consultar una tabla comments_post_X, donde X es el ID de fragmento calculado en función de un esquema de hashing consistente. Todas estas tablas viven en un solo esquema, en una sola instancia de base de datos.

Además, lanzaron algún código como parte de una aplicación de muestra que demuestra cómo se fragmentan.

Tengo un proyecto Django basado en múltiples servidores PostgreSQL .

Quiero que los usuarios se sharded en esos servidores de bases de datos utilizando la misma lógica de fragmentación que usa Instagram :

ID de usuario => ID de fragmento lógico => ID de fragmento físico => servidor de base de datos => esquema => tabla de usuario

  • El ID de fragmento lógico se calcula directamente a partir del ID de usuario (13 bits incrustados en el ID de usuario).
  • La asignación del ID de fragmento lógico a físico está codificada (en algún archivo de configuración o tabla estática).
  • La asignación del ID de fragmento físico al servidor de la base de datos también está codificada. Instagram usa Pgbouncer en este punto para recuperar una conexión de base de datos agrupada al servidor de base de datos apropiado.
  • Cada fragmento lógico vive en su propio esquema PostgreSQL (para aquellos que no están familiarizados con PostgreSQL, este no es un esquema de tabla, es más bien como un espacio de nombres, similar a las "bases de datos" de MySQL ). El esquema simplemente se llama algo así como "shardNNNN", donde NNNN es el ID de fragmento lógico.
  • Finalmente, se consulta la tabla de usuario en el esquema apropiado.

¿Cómo se puede lograr esto tan simple como sea posible en Django?

Idealmente, me encantaría poder escribir código Django como:

Recuperando una instancia

# this gets the user object on the appropriate server, in the appropriate schema: user = User.objects.get(pk = user_id)

Obteniendo objetos relacionados

# this gets the user''s posted articles, located in the same logical shard: articles = user.articles

Creando una instancia

# this selects a random logical shard and creates the user there: user = User.create(name = "Arthur", title = "King") # or: user = User(name = "Arthur", title = "King") user.save()

Buscando usuarios por nombre

# fetches all relevant users (kings) from all relevant logical shards # - either by querying *all* database servers (not good) # - or by querying a "name_to_user" table then querying just the # relevant database servers. users = User.objects.filter(title = "King")

Para hacer las cosas aún más complejas, utilizo Streaming Replication para replicar los datos de cada servidor de base de datos en múltiples servidores esclavos. Los maestros deben usarse para escrituras, y los esclavos deben usarse para lecturas.

Django proporciona soporte para el enrutamiento automático de la base de datos que probablemente sea suficiente para la mayoría de los anteriores, pero estoy atascado con User.objects.get(pk = user_id) porque el enrutador no tiene acceso a los parámetros de consulta, por lo que no sabe En qué consiste el ID de usuario, simplemente sabe que el código está intentando leer el modelo del usuario.

Soy consciente de que la fragmentación probablemente debería usarse solo como una optimización de último recurso, ya que tiene limitaciones y realmente hace que las cosas sean bastante complejas. La mayoría de las personas no necesitan fragmentación: una arquitectura maestro / esclavo optimizada puede recorrer un largo camino. Pero supongamos que necesito fragmentación.

En resumen: ¿cómo puedo compartir datos en Django de la manera más simple posible?

Muchas gracias por su amable ayuda.

Nota

Existe una pregunta que es bastante similar, pero en mi humilde opinión es demasiado general y carece de ejemplos precisos. Quería limitar las cosas a una técnica de fragmentación en particular que me interesa (la forma de Instagram).


Realmente no quieres estar en la posición de hacer esta pregunta. Si está fragmentado por la identificación del usuario, entonces probablemente no quiera buscar por nombre.

Si usted está fragmentando su base de datos, entonces no será invisible para su aplicación y probablemente terminará requiriendo alteraciones de esquema.

Puede encontrar útil http://pgfoundry.org/projects/skytools/ - lea en pl / proxy. Así es como Skype fragmenta sus bases de datos.