amazon-dynamodb - tabla - dynamodb create table
Cambie el esquema de una tabla de DynamoDB: ¿cuál es la mejor/forma recomendada? (3)
¿Cuál es la forma recomendada por Amazon de cambiar el esquema de una tabla grande en un DynamoDB de producción?
Imagine un caso hipotético en el que tenemos una persona de mesa, con clave de hash principal SSN. Esta tabla puede contener 10 millones de artículos.
Ahora llega la noticia de que, debido al volumen crítico de robos de identidad, el gobierno de este país hipotético ha introducido otra identificación personal: Identificador personal único o UPI.
Tenemos que agregar una columna UPI y cambiar el esquema de la tabla de Personas, de modo que ahora la clave de hash principal sea UPI. Queremos admitir durante algún tiempo tanto el sistema actual, que usa SSN como el nuevo sistema, que usa UPI , por lo que necesitamos que estas dos columnas coexistan en la tabla de Personas.
¿Cuál es la forma recomendada por Amazon de hacer este cambio de esquema?
Estoy usando una variante del tercer enfoque de Alexander. Nuevamente, creará una nueva tabla que se actualizará a medida que se actualice la tabla anterior. La diferencia es que utiliza el código en el servicio existente para escribir en ambas tablas mientras realiza la transición en lugar de usar una función lambda. Es posible que tenga un código de persistencia personalizado que no desea reproducir en una función lambda temporal y es probable que tenga que escribir el código de servicio para esta nueva tabla de todos modos. Dependiendo de su arquitectura, puede incluso cambiar a la nueva tabla sin tiempo de inactividad.
Sin embargo, lo bueno de usar una función lambda es que cualquier carga introducida por escrituras adicionales en la nueva tabla estaría en la lambda, no en el servicio.
Hay un par de enfoques, pero primero debe comprender que no puede cambiar el esquema de una tabla existente. Para obtener un esquema diferente, debe crear una nueva tabla. Es posible que pueda reutilizar su tabla existente, pero el resultado sería el mismo que si creara una tabla diferente.
- Migración perezosa a la misma tabla, sin Streams. Cada vez que modifique una entrada en la tabla de Persona, cree un nuevo elemento en la tabla de Persona utilizando UPI y no SSN como el valor para la clave de hash, y elimine el elemento antiguo ingresado en SSN. Esto supone que UPI se basa en un rango de valores diferente al de SSN. Si el SSN se parece a XXX-XX-XXXX, entonces mientras UPI tenga un número de dígitos diferente al de SSN, nunca tendrá una superposición.
- Migración perezosa a la misma tabla, utilizando Streams. Cuando las transmisiones estén disponibles de forma general, podrá activar una tabla Secuencia para su persona. Cree un flujo con el tipo de vista de flujo NEW_AND_OLD_IMAGES, y cada vez que detecte un cambio en un elemento que agregue un UPI a una persona existente en la tabla Persona, cree una función Lambda que elimine a la persona ingresada en el SSN y agregue una persona con el mismo atributos ingresados en la UPI. Este enfoque tiene condiciones de carrera que se pueden mitigar agregando un atributo atómico de contra-versión al artículo y condicionando la llamada DeleteItem en el atributo de la versión.
- Migración preventiva (con script) a una tabla diferente, utilizando Streams. Ejecute un script que escanea su tabla y agrega un UPI único a cada elemento de persona en la tabla de persona. Cree un flujo en la tabla de Personas con el tipo de vista de flujo NEW_AND_OLD_IMAGES y suscriba una función lambda a ese flujo que escribe todas las nuevas Personas en una nueva tabla Person_UPI cuando la función lambda detecta que una Persona con un UPI cambió o cuando una Persona tenía una UPI agregó. Las mutaciones en la tabla base suelen tardar cientos de milisegundos en aparecer en una secuencia como registros de secuencias, por lo que puede realizar una conmutación por error en caliente a la nueva tabla Person_UPI en su aplicación. Rechace las solicitudes durante unos segundos, apunte su aplicación a la tabla Person_UPI durante ese tiempo y vuelva a habilitar las solicitudes.
Las secuencias de DynamoDB nos permiten migrar tablas sin ningún tiempo de inactividad. He hecho esto muy eficaz, y los pasos que he seguido son:
- Cree una nueva tabla (llamemos a esta Nueva Tabla), con la estructura de claves deseada, LSI, GSI.
- Habilitar DynamoDB Streams en la tabla original
- Asocie una Lambda a la secuencia, que empuja el registro a NewTable. (Este Lambda debería recortar la bandera de migración en el Paso 5)
- [ Opcional ] Cree un GSI en la tabla original para acelerar el escaneo de elementos. Asegúrese de que este GSI solo tenga atributos: clave principal y migrado (consulte el Paso 5).
Escanee el GSI creado en el paso anterior (o en toda la tabla) y use el siguiente Filtro:
FilterExpression = "attribute_not_exists (Migrated)"
Actualice cada elemento de la tabla con un indicador de migración (es decir, "Migrado": {"S": "0"}, que lo envía a las transmisiones de DynamoDB (utilizando la API UpdateItem, para garantizar que no se produzcan pérdidas de datos).
NOTA : Es posible que desee aumentar las unidades de capacidad de escritura en la tabla durante las actualizaciones.
- La Lambda recogerá todos los elementos, recortará la bandera Migrada y la insertará en NewTable.
- Una vez que se hayan migrado todos los elementos, vuelva a colocar el código en la nueva tabla
- Retire la mesa original, y la función Lambda una vez feliz, todo es bueno.
Si sigue estos pasos, debe asegurarse de que no haya pérdida de datos ni tiempo de inactividad.
He documentado esto en mi blog, con un código para ayudar: https://www.abhayachauhan.com/2018/01/dynamodb-changing-table-schema/