Tengo una pregunta relacionada con el diseño del esquema HBase. El problema es bastante simple: estoy almacenando "notificaciones" en hbase, cada una de las cuales tiene un estado ("nuevo", "visto" y "leído"). Aquí están las API necesito proporcionar:Diseño del esquema de HBase para admitir mejor las consultas específicas
- conseguir todas las notificaciones para un usuario
- Obtener todos los "nuevos" notificaciones para un usuario
- obtener el recuento de todos los "nuevos" notificaciones para un usuario
- Actualizar el estado de una notificación
- Actualizar el estado de todas las notificaciones de un usuario
- obtener todos los "nuevos" notificaciones al otro lado de la base de datos
- Notificaciones sho uld puede escanearse en orden cronológico inverso y permitir la paginación.
Tengo algunas ideas, y quería ver si una de ellas es claramente la mejor, o si me he perdido una buena estrategia por completo. Común a los tres, creo que tener una fila por notificación y tener la identificación de usuario en la clave de fila es el camino a seguir. Para obtener un orden cronológico de la paginación, también necesito tener una marca de tiempo invertida allí. Me gustaría guardar todos los elementos en una tabla (para no tener que combinar la ordenación para la llamada "obtener todos las notificaciones para un usuario") y no quiero escribir trabajos por lotes para tablas de índice secundarias (ya que las actualizaciones a el recuento y el estado deberían ser en tiempo real).
La forma más sencilla de hacerlo sería (1) la clave de fila es "userId_reverseTimestamp" y filtrar el estado en el lado del cliente. Esto parece ingenuo, ya que enviaremos muchos datos innecesarios a través de la red.
La siguiente posibilidad es (2) codificar el estado en la clave de fila también, por lo tanto, o bien "userId_reverseTimestamp_status" y luego hacer el filtrado de la expresión regular de la fila en los escaneos. El primer problema que veo es la necesidad de eliminar una fila y copiar los datos de notificación a una nueva fila cuando el estado cambia (lo que presumiblemente debería ocurrir exactamente dos veces por notificación). Además, dado que el estado es la última parte de la clave de fila, para cada usuario, estaremos escaneando muchas filas adicionales. ¿Es esto un gran golpe de rendimiento? Finalmente, para cambiar el estado, tendré que saber cuál era el estado anterior (para construir la clave de fila) o tendré que hacer otro análisis.
La última idea que tuve es que (3) tenga dos familias de columnas, una para los datos de notificación estáticos y otra como bandera para el estado, es decir, "s: leer" o "s: nuevo" con "s 'como el cf y el estado como el calificador. Habría exactamente uno por fila, y puedo hacer un MultipleColumnPrefixFilter o SkipFilter con ColumnPrefixFilter contra ese cf. Aquí también, tendría que eliminar y crear columnas en el cambio de estado, pero debería ser mucho más ligero que copiar filas enteras. Mi única preocupación es la advertencia en el libro de HBase de que a HBase no le va bien con "más de 2 o 3 familias de columnas", quizás si el sistema necesita ampliarse con más capacidades de consulta, la estrategia multi-cf no escalará. .
Parece que (1) tendría demasiada sobrecarga de red. (2) parece que habría desperdiciado el costo de copiar los datos y (3) podría causar problemas con demasiadas familias. Entre (2) y (3), ¿qué tipo de filtro debería proporcionar un mejor rendimiento? En ambos casos, el escaneo tendrá en cuenta cada fila para un usuario, que presumiblemente tiene notificaciones en su mayoría leídas, lo que tendría un mejor rendimiento. Creo que me inclino por (3): ¿hay otras opciones (o ajustes) que me he perdido?
¿Las notificaciones indican 'nuevo' y 'leído' solo con una única transición posible de nueva a lectura? ¿Cuál es el volumen de estas notificaciones? – Gevorg