FINALIDAD DEL SERVICIO DE GUÍA DE LA CIUDAD
La guía de la ciudad será el servicio que permita a los usuarios buscar y encontrar lugares cercanos a la ubicación del usuario. Puedes pensar que este servicio será similar a Foursquare. Antes de comenzar a diseñar el sistema, será bueno definir el propósito del sistema. Lo que significa que, antes del proceso de diseño, los requisitos deben ser claros y bien definidos. El propósito del servicio de guía de la ciudad es presentar ubicaciones a los usuarios en función de sus ubicaciones. Puede encontrar cualquier lugar como restaurantes, teatros, cines y más. Las sugerencias comenzarán desde ubicaciones cercanas a ubicaciones lejanas, pero el sistema también admitirá la búsqueda de lugares en función de ubicaciones dedicadas.
REQUISITOS Y LÍMITES DEL SISTEMA
Si desea diseñar un sistema, primero debe definir los requisitos y los límites del sistema. Antes de empezar a diseñar, tendrás el Documento de Diseño del Servicio y definirás todos los requisitos desde cero. Dado que el propósito del servicio de guía de la ciudad es crear un servicio de guía de la ciudad bien diseñado, debe poder recomendar lugares en función de su consulta de búsqueda y ubicación. Por lo tanto, nuestro sistema admitirá estas funciones;
– Los usuarios deben poder crear una cuenta.
– Los usuarios deben poder iniciar sesión en el sistema.
– Los usuarios deben poder cerrar sesión en el sistema.
– Los usuarios deben poder buscar lugares como un restaurante, teatro, café, cine y más cuando inician sesión o cierran sesión.
– Los usuarios deben poder agregar comentarios a los lugares si inician sesión.
– Los usuarios deben poder indicar que les gusta o no les gustan los lugares.
– Los usuarios deben poder agregar un nuevo lugar y el administrador del sistema debe revisarlo.
– Los usuarios deben poder agregar imágenes a los lugares.
– Los usuarios deben poder actualizar o eliminar lugares si tienen un permiso.
– El sistema debe poder sugerir lugares desde los más relevantes hasta los menos relevantes.
– El sistema debe poder sugerir lugares en función de la consulta y la ubicación del usuario.
– El sistema debe poder sugerir lugares en función de la popularidad y las opiniones de los usuarios.
– El sistema debe ser capaz de monitorear.
– El sistema debe poder recomendar nuevos lugares mediante el envío de notificaciones automáticas.
– El sistema debe tener alta disponibilidad.
– El sistema debe ser altamente confiable.
– El sistema debe ser duradero.
– El sistema debe ser resiliente.
– El sistema debe ser muy rentable y eficiente en cuanto a rendimiento.
Básicamente, el sistema debe soportar 5 pilares importantes, estos son;
– Disponibilidad
– Confiabilidad
– Resiliencia
– Durabilidad
– Costo Rendimiento
Estos son los pilares que debemos considerar juntos ya que están acoplados entre sí. En resumen, disponibilidad significa que el sistema debe estar siempre disponible. Confiabilidad significa que el sistema debe funcionar como se espera. Resiliencia significa cómo y cuándo el sistema se recuperará si hay algún problema. La durabilidad es el único pilar en el que cada parte del sistema debe existir hasta que lo eliminemos. El desempeño de costos también es un tema importante que básicamente se relacionará con el uso de servicios bajo la eficiencia de costos. Se puede ilustrar como si el sistema se construyera en AWS y fuera suficiente usar instancias t2 micro EC2, no habrá ninguna razón para usar instancias EC2 más grandes y pagar dinero extra.
Tenga en cuenta que cada sistema crecerá día a día, por lo que los sistemas serán más complejos en el futuro (como después de 5 años), pero lo importante es que si tiene una estructura y requisitos bien definidos, no habrá demasiado trabajo para agregar nuevos componentes. a su sistema.
Cuando se definen los límites del sistema y los requisitos funcionales, es necesario pensar en opciones en la nube o bajo promesa. Los servicios en la nube tienen muchas ventajas, como rentabilidad, rendimiento de alta velocidad, soluciones de respaldo, mantenimiento, capacidad de almacenamiento ilimitada y más. Su sistema puede ser;
– %100 on-promise (su propio centro de datos/servidor)
– %100 cloud (AWS, Google Cloud, Azure)
– Mezcla de on-promise y nube (puede tener ambos durante el proceso de migración)
La estimación de la capacidad será importante en primer lugar (especialmente para los servicios bajo promesa) para que pueda estimar cuántos servidores necesita o cómo separar sus servicios y qué base de datos usará. También tenga en cuenta que su sistema tendrá muchas lecturas y el tráfico de lectura será mayor que el tráfico de escritura.
Supongamos que habrá 10 millones de lugares en el sistema de guías de ciudades en 5 años y que el número de consultas diarias llegará a 10.000. Puede estimar que el sistema crecerá cada año y puede estimar el búfer. Esto significa que mantendrás la información de 10 millones de lugares con sus metadatos y también imágenes. Si asumimos un tamaño promedio de foto de 25 KB y cada lugar tiene un promedio de 5 imágenes;
La capacidad será aproximadamente igual a 10 millones * 5 * 25 KB + (información de metadatos de usuario) + (información de metadatos de ubicación). Se recomienda contar con soluciones de replicación y respaldo de datos para evitar la pérdida de datos por lo que será aproximadamente 3 veces más grande de lo que estimamos.
Este cálculo es solo un breve ejemplo de cómo definir la capacidad del sistema y no calcularemos la capacidad de carga/descarga diaria ni las capacidades de metadatos, pero debe considerar este cálculo (y la estimación de la capacidad de lectura/escritura diaria) para escalar servicios/bases de datos.
API ESTIMACIÓN
El servicio de guía de la ciudad puede admitir la estrategia REST o SOAP. También puede pensar en GRPC, esta es una nueva estrategia que proviene de Google y la mayor ventaja de GRPC es usar un ancho de banda y recursos más pequeños. Si continuamos con REST, habrá cuatro API principales para diseñar el sistema.
– AddPlace (api_dev_key, nombre, descripción, longitud, latitud, categoría, imágenes): esta API devuelve una respuesta HTTP con la información del lugar recién agregado. (202 aceptado si tiene éxito)
– DeletePlace(api_dev_key, placeID): puede devolver la respuesta HTTP 200 (OK) o 204 (Sin contenido) según su respuesta.
– UpdatePlace(api_dev_key, updatePlaceRequest): updatePlaceRequest tendrá un ID de lugar para saber qué lugar estamos actualizando.
– GetPlace(search_query, userlocation, categoryfilter = null, sortby = ‘distancia || popularidad’, page = 1, distanceRadius = 5, maximum_return_count = 20): devuelve JSON con metadatos de ubicaciones. Los resultados se ordenarán según la consulta del usuario y la ubicación.
ESQUEMA DE DISEÑO Y BASE DE DATOS
El guardado de los datos se distribuirá en 2 partes. El primero estará relacionado con mantener contenido estático como imágenes de ubicación. Podemos usar S3 para mantener contenidos estáticos si estamos construyendo nuestro servicio AWS y frente a S3, podemos usar Cloudfront como CDN. Cloudfront actuará como un caché y ayudará al sistema a devolver la respuesta rápidamente. Si está construyendo su sistema como una promesa, entonces necesita tener almacenamiento de imágenes. S3 es una oferta de AWS y ayudará a nuestro sistema a mantener contenidos multimedia estáticos de forma segura. Para los metadatos (lugares, imágenes, usuarios) podemos usar SQL y NoSQL. NoSQL es la mejor manera de escalar el sistema fácilmente. Por otro lado, si pensamos en las relaciones y restricciones de SQL, escalar bases de datos SQL es muy difícil.
– Lugar: ID, Agregado por, Nombre, Lat, Lng, Categoría, Descripción, Fecha agregada, LikeCount, DisLikeCount
– Usuario: ID, Nombre de usuario, Contraseña, Correo electrónico, Fecha de registro, LastLoginDate
– Comentario: ID, Me gusta, No me gusta, Comentario, Fecha de comentario
– UserPlaceComment : ID, ID de comentario, ID de usuario, ID de lugar
8 bytes serán suficientes para mantener placeID y userID. Además, mantendremos la longitud y la latitud con 8 bytes. Los datos se indexarán según placeID, lat y lng. Enviaremos una consulta a la tabla de lugares según la ubicación del lugar y la ubicación del usuario. Entonces la consulta evaluará;
(Lugares donde placeLongitude entre userLongitude – Radius y userLongitude + Radius y placeLatitude entre userLatitude – Radius y userLatitude + Radius)
Esta forma no es la óptima ya que necesitamos calcular tanto la latitud como la longitud. Podemos usar una cuadrícula para resolver problemas de rendimiento. Podemos dividir el mundo entero en cuadrículas más pequeñas. Esto asegura que solo podamos tratar con el vecino de las redes. Gracias a este método, solo nos enfocamos en la cuadrícula de ubicación del usuario y sus cuadrículas vecinas. Un mapa es la mejor opción para usar una cuadrícula. La clave es el gridID. El valor son los lugares completos en esta cuadrícula. Entonces la consulta evaluará;
(Lugares donde Latitud entre userLatitude – Radius y userLatitude + Radius y GridID en (cuadrículas vecinas)
Tenga en cuenta que, por supuesto, tendremos más tablas de base de datos y estas son solo una muestra. Será bueno seguir las reglas de normalización para el proceso de diseño de bases de datos.
También podemos particionar el sistema en base a;
– ID de usuario –
ID de región
– ID de ubicación
El uso de ID de usuario y ID de región puede crear un problema de distribución. Algunas regiones pueden tener más ubicaciones que otras y, en ese caso, el sistema no se distribuirá uniformemente. Podemos particionar en función de ID de ubicación y ID de región.
CONSIDERACIÓN DE DISEÑO DEL SISTEMA
Si estamos diseñando un sistema, los conceptos básicos que necesitamos son;
– Cliente
– Servicios
– Servidor web
– Servidor de aplicaciones
– Almacenamiento de archivos multimedia
– Base de datos
– Almacenamiento en caché
– Replicación
– Redundancia
– Equilibrio de carga
– Fragmentación
Como mencionamos anteriormente, el proceso de replicación es un proceso valioso para proporcionar alta disponibilidad, alta confiabilidad y experiencia en tiempo real. La replicación y el respaldo son dos conceptos importantes para proporcionar los pilares que mencionamos anteriormente. La replicación es un concepto muy importante para manejar una falla de servicios o servidores. La replicación se puede aplicar a servidores de bases de datos, servidores web, servidores de aplicaciones, almacenamiento de medios, etc. En realidad, podemos replicar todas las partes del sistema. (Algunos de los servicios de AWS, como Route53, son altamente disponibles en sí mismos, por lo que no es necesario que se ocupe de la replicación de Route53, el balanceador de carga, etc.) Tenga en cuenta que la replicación también ayuda al sistema a reducir el tiempo de respuesta. Imagínese, si dividimos las requests entrantes en más recursos en lugar de un recurso, el sistema puede satisfacer fácilmente todas las requests entrantes. Además, el número óptimo de una réplica para cada recurso es 3 o más. Puede proporcionar redundancia manteniendo los datos en una zona de disponibilidad diferente o una región diferente en AWS. Podemos mantener los mismos datos en tres recursos diferentes y, gracias a este proceso, si un servidor muere, el sistema continúa automáticamente trabajando en réplicas. Una ventaja más de la replicación es que el sistema puede continuar ejecutándose en una actualización del sistema. En el proceso de replicación, el servidor Master será responsable de las operaciones de escritura y lectura; y los esclavos son responsables de las operaciones de lectura. el sistema automáticamente continúa trabajando réplicas. Una ventaja más de la replicación es que el sistema puede continuar ejecutándose en una actualización del sistema. En el proceso de replicación, el servidor Master será responsable de las operaciones de escritura y lectura; y los esclavos son responsables de las operaciones de lectura. el sistema automáticamente continúa trabajando réplicas. Una ventaja más de la replicación es que el sistema puede continuar ejecutándose en una actualización del sistema. En el proceso de replicación, el servidor Master será responsable de las operaciones de escritura y lectura; y los esclavos son responsables de las operaciones de lectura.
El equilibrio de carga se refiere a la distribución de requests entre un grupo de servicios y servidores. Cuando hemos hablado de la replicación y el sharding, se debe dirigir una solicitud entrante y esto lo hace un balanceador de carga. Podemos usar el método Round-Robin para redirigir las requests entrantes, pero puede haber un problema en este caso. Round-Robin deja de enviar requests a servidores muertos, pero Round-Robin no puede dejar de enviar requests a un servidor expuesto a mucho tráfico. Podemos preparar un algoritmo inteligente Round-Robin para eliminar este problema. Además, podemos usar hashing consistente para redirigir las requests entrantes. El hashing consistente asegura que el sistema se distribuya de manera más uniforme.
El posible problema de la fragmentación con un balanceador de carga es cómo reconstruimos el sistema cuando este muere. El enfoque posible es la fuerza bruta. Este método es lento porque necesitamos reconstruir todo el sistema desde el principio. Podemos eliminar este problema utilizando el enfoque de indexación inversa. Podemos tener otro servidor de índice que contendrá toda la información sobre la indexación inversa. El índice inverso mapea todos los lugares. Necesitamos construir un mapa y la clave es el ID del servidor y el valor es todos los lugares.
Para las estrategias de almacenamiento en caché, podemos usar un mecanismo de almacenamiento en caché global mediante el uso de servidores de caché. Podemos usar Redis o Memcache, pero la parte más importante de la estrategia de almacenamiento en caché es cómo proporcionar el desalojo de caché. Si usamos servidores de caché global, garantizaremos que cada usuario verá los mismos datos en el caché, pero habrá tiempo de latencia si usamos servidores de caché global. Como estrategias de almacenamiento en caché, podemos usar el algoritmo LRU (Usado menos recientemente).
Para el almacenamiento en caché de archivos multimedia, como mencionamos antes, usaremos CDN. CDN está ubicado en diferentes ubicaciones de borde, por lo que el tiempo de respuesta será menor que obtener contenido multimedia directamente desde AWS S3.
Podemos tener varios mecanismos de clasificación que son los más populares, los más relevantes, los más nuevos, etc. Como sabe, podemos tener muchos servidores y necesitamos obtener datos de estos servidores. Por esta razón, necesitamos agregar la función para combinar todos estos datos para obtener la solución más deseable.
CODIFICACIÓN BÁSICA DEL SISTEMA
// Java Program to illustrate the Design public enum UserStatus{ LOGIN, LOGOUT ... } public enum ReviewStatus { LIKE, DISLIKE } public enum LocationStatus{ PUBLIC, PRIVATE, ... } public enum LocationCategory { EVENT, EDUCATION, FOOD, HEALTH, ENTERTAINTMENT, .... } public class AddressDetails { private String street; private String city; private String country; private double latitude; private double longitude; ... } public class AccountDetails { private Date createdTime; private AccountStatus status; private boolean updateAccountStatus(AccountStatus accountStatus); ... } public class Comment { private Integer id; private User addedBy; private Date addedDate; private String comment; public boolean updateComment(String comment); ... } public class Location { private Integer id; private User createdBy; private LocationCategory locationCategory; private LocationStatus locationStatus; private HashSet<Integer> pictures; private HashSet<Integer> userLikes; private HashSet<Integer> userDisLikes; private HashSet<Integer> userComments; ... } public class User { private UserStatus userStatus; private Double latitude; private Double longitude; private AccountDetails accountDetails; private UserRelations userRelations; public List<User> searchLocation(query); ... } public LoginUser extends Users{ private int id; private String password; private String nickname; private String email; private boolean updatePassword(); public boolean addPlace(Place place); public boolean updatePlace(Place place); public boolean addComment(Integer placeID, String comment); public boolean reviewPlace(Integer placeID, ReviewStatus status); .... }
Referencia: https://developer.foursquare.com/docs/resources/
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.