Mejores prácticas para optimizar el cumplimiento, la estabilidad y el rendimiento de las instancias de ApsaraDB RDS for PostgreSQL.
Pool de conexiones
Configurar parámetros del pool de conexiones
Utilice objetos PreparedStatement para almacenar en caché las sentencias SQL dentro del pool de conexiones. Esto elimina los análisis sintácticos completos, reduce el uso de CPU y mejora el rendimiento de la instancia.
Minimice las conexiones inactivas para disminuir el consumo de memoria, aumentar la eficiencia de GetSnapshotData() y mejorar el rendimiento general del sistema.
Habilite el pool de conexiones en su aplicación para evitar la sobrecarga que generan las conexiones de corta duración. Si su aplicación no admite un pool de conexiones integrado, coloque uno entre la aplicación y la instancia de RDS; por ejemplo, PgBouncer o Pgpool-II.
Establezca los siguientes parámetros para su pool de conexiones:
|
Parámetro |
Valor recomendado |
Descripción |
|
|
1 |
Número mínimo de conexiones inactivas. Establecer este valor en 1 reduce las conexiones inactivas. |
|
|
1 |
Número máximo de conexiones inactivas. Solo aplica si el parámetro está disponible, ya que se ha eliminado en la mayoría de las implementaciones de pools de conexiones. |
|
|
60 minutos |
Tiempo de vida máximo (TTL) por conexión. Reduce los errores de falta de memoria (OOM) causados por conexiones frecuentes a RelCache. |
|
|
15 |
Conexiones máximas por pool. Adecuado para la mayoría de las cargas de trabajo. Incremente este valor en los clientes de base de datos solo si su instancia maneja cargas de trabajo provenientes de más conexiones de las que el pool puede atender. |
Configuraciones recomendadas por framework
Las siguientes configuraciones aplican a los frameworks de pool de conexiones más comunes. No incluyen ajustes de PreparedStatement; configúrelos según los requisitos de su aplicación.
HikariCP (recomendado para Java):
minimumIdle=1, maximumPoolSize=15, idleTimeout=600000 (10 minutes), maxLifetime=3600000 (60 minutes)
GORM (recomendado para Go):
sqlDB.SetMaxIdleConns(1), sqlDB.SetMaxOpenConns(15), sqlDB.SetConnMaxLifetime(time.Hour)
Druid (Java):
initialSize=1, minIdle=1, maxIdle=1, maxActive=15, testOnBorrow=false, testOnReturn=false, testWhileIdle=true, minEvictableIdleTimeMillis=600000 (10 minutes), maxEvictableIdleTimeMillis=900000 (15 minutes), timeBetweenEvictionRunsMillis=60000 (1 minute), maxWait=6000 (6 seconds)
Rendimiento y estabilidad
Una sola base de datos corresponde a una carpeta en el sistema de archivos subyacente. Las tablas, particiones e índices corresponden a archivos dentro de esa carpeta. Si la cantidad de archivos supera los 20 millones, la instancia reportará un error de espacio en disco agotado. Divida la base de datos o fusione los archivos de tabla según su carga de trabajo.
Use
CREATE INDEX CONCURRENTLYpara crear índices en cargas de trabajo en línea. Esto evita bloquear las operaciones INSERT, UPDATE y DELETE sobre la tabla destino en otras sesiones.Para instancias con PostgreSQL 12 o posterior, use
REINDEX CONCURRENTLYpara reconstruir índices. En PostgreSQL 11 o anterior, utiliceCREATE INDEX ... CONCURRENTLYpara crear un índice de reemplazo y luego elimine el original.Evite crear y eliminar tablas temporales con frecuencia, pues esto incrementa la sobrecarga de las tablas del sistema. Tenga precaución con
ON COMMIT DROP. En la mayoría de los casos, utilice una cláusulaWITHen lugar de una tabla temporal.PostgreSQL 13 mejora la compatibilidad con tablas particionadas, las operaciones
HashAggregatepara cláusulasGROUP BYy las consultas paralelas. Actualice su instancia a PostgreSQL 13 siempre que sea posible. Para obtener más información, consulte Upgrade the major engine version of an ApsaraDB RDS for PostgreSQL instance.Deshabilite la función de cursor si ya no la utiliza.
Utilice
TRUNCATEen lugar deDELETEpara eliminar datos a nivel de tabla, ya queTRUNCATEes significativamente más rápido.Envuelva las sentencias DDL en transacciones para poder revertirlas si es necesario. Mantenga las transacciones breves: las transacciones DDL largas bloquean las operaciones de lectura sobre los objetos que tienen bloqueados.
Para escrituras masivas de datos, utilice
COPYoINSERT INTO table VALUES (),(),...();con múltiples filas para maximizar el throughput de escritura.
Versión menor del motor
Para utilizar la función de slot de replicación, actualice la versión menor del motor a 20201230 o posterior. Esto habilita la función Logical Replication Slot Failover y permite configurar una regla de alerta para la métrica Maximum Replication Slot Latency, lo que evita que las suscripciones lógicas se retrasen o se interrumpan. Si las suscripciones lógicas se retrasan o interrumpen, se pierden los slots de replicación y se acumulan registros de write-ahead logging (WAL). Para obtener más información, consulte Logical Replication Slot Failover y Manage the alert rules of an ApsaraDB RDS for PostgreSQL instance.
-
Para usar la función de registro de auditoría o la función Performance Insight, actualice la versión menor del motor a 20211031 o posterior.
Cuando
log_statementse establece enall, el rendimiento mejora aproximadamente cuatro veces en escenarios con más de 50 conexiones activas, y se evitan picos significativos en la utilización de CPU.
Monitoreo y alertas
Active Initiative Alert para habilitar las reglas de alerta predeterminadas que proporciona la función de monitoreo y alertas. Para obtener más información, consulte Manage the alerts.
Establezca el umbral de alerta de uso de memoria entre 85% y 95% según las características de su carga de trabajo.
Solución de problemas
Para identificar las sentencias SQL con mayor consumo de recursos (Top SQL), consulte Find the most resource-intensive SQL statements (Top SQL).
Para identificar las sentencias SQL con mayor consumo de recursos, consulte Locate SQL statements with the highest resource consumption.
Diseño
Permisos
Siga el principio de menor privilegio (PoLP) y gestione los permisos por esquema o rol. Cree dos roles para cada instancia: uno con permisos de lectura y escritura, y otro con permisos de solo lectura. Para obtener más información, consulte Manage permissions in an ApsaraDB RDS for PostgreSQL instance.
Si implementa la separación de lectura/escritura en la capa de aplicación, asigne el rol de solo lectura a los clientes de base de datos de solo lectura.
Tablas
Asegúrese de que los tipos de datos en su esquema coincidan con los tipos de datos de su aplicación, y aplique reglas de validación consistentes en todas las tablas. Esto previene errores de incompatibilidad de tipos y garantiza el uso correcto de los índices.
Para tablas cuyos datos históricos se purgan regularmente, realice el particionamiento por año o mes. Utilice
DROPoTRUNCATEsobre las particiones secundarias para eliminar datos; evite ejecutarDELETEen dichas particiones.-
En tablas con actualizaciones frecuentes, establezca
FILLFACTORen85al momento de la creación. Esto reserva el 15% del almacenamiento por página para actualizaciones en caliente, lo que reduce la división de páginas.CREATE TABLE test123(id int, info text) WITH(FILLFACTOR=85); -
Utilice las siguientes convenciones de nomenclatura:
Tablas temporales: los nombres comienzan con
tmp_Tablas de partición secundaria: los nombres terminan con el valor de la clave de partición. Por ejemplo, si la tabla principal es
tbly está particionada por año, las tablas secundarias se nombran comotbl_2016,tbl_2017, etc.
Índices
ApsaraDB RDS for PostgreSQL admite los siguientes tipos de índices: B-tree, Hash, GIN, GiST, SP-GiST, BRIN, RUM, Bloom y PASE. RUM, Bloom y PASE son tipos de índices extendidos.
Elección del tipo de índice:
B-tree: Es el tipo de índice predeterminado. Los campos no deben exceder los 2,000 bytes en total. Si el tamaño total de los campos indexados supera los 2,000 bytes, cree un índice basado en funciones (como un índice hash) o procese los datos mediante un analizador antes de indexarlos.
-
BRIN: Úselo en tablas grandes donde los valores de las columnas tengan un orden lineal natural, como marcas de tiempo, IDs autoincrementales o datos de streaming. Los índices BRIN son compactos y aceleran las consultas por rango.
CREATE INDEX idx ON tbl USING BRIN(id);
Evite los escaneos completos de tabla, excepto cuando necesite escanear y analizar grandes conjuntos de datos. La mayoría de los tipos de datos de PostgreSQL admiten índices.
Convenciones de nomenclatura de índices:
|
Tipo de índice |
Prefijo |
|
Índices de clave primaria |
|
|
Índices únicos |
|
|
Índices regulares |
|
Tipos de datos y conjuntos de caracteres
Seleccione tipos de datos que se ajusten a la información que almacena. Evite usar tipos de cadena para datos numéricos o para datos que encajan naturalmente en estructuras de árbol, ya que los tipos de datos adecuados mejoran la eficiencia de las consultas.
ApsaraDB RDS for PostgreSQL admite una amplia variedad de tipos de datos, entre ellos: Numeric, Floating-Point, Monetary, String, Character, Binary, Date/Time, Boolean, Enumerated, Geometry, Network Address, Bit String, Text Search, UUID, XML, JSON, Array, Composite, Range, Object identifier, row number, large object, estructura ltree, Data Cube, geography, H-Store, módulo pg_trgm, PostGIS y HyperLogLog. PostGIS admite tipos de punto, segmento de línea, superficie, ruta, latitud, longitud, ráster y topología. HyperLogLog es una estructura de datos similar a un conjunto, de tamaño fijo, diseñada para contar valores distintos con una precisión ajustable.
Establezca LC_COLLATE en C en lugar de UTF8. La intercalación C ofrece un rendimiento superior al de UTF8. Si utiliza la intercalación UTF8, debe especificar la clase de operador text_pattern_ops en los índices para admitir consultas LIKE.
Procedimientos almacenados
Para lógica de negocio compleja que requiera muchos viajes de ida y vuelta entre la aplicación y la base de datos, utilice procedimientos almacenados (como los basados en PL/pgSQL) o funciones integradas para reducir las interacciones entre la aplicación y la base de datos. PostgreSQL admite funciones analíticas, funciones de agregación, funciones de ventana, funciones matemáticas y funciones geométricas.
Consulta de datos
Utilice
COUNT(*)en lugar deCOUNT(column_name)oCOUNT(constants).COUNT(*)es el estándar SQL-92 para contar filas e incluye valores NULL.COUNT(column_name)excluye los valores NULL y produce un resultado diferente.-
Para
COUNT(DISTINCT)en varias columnas, encierre la lista de columnas entre paréntesis:COUNT( (col1, col2, col3) )COUNT(DISTINCT)incluye todos los valores NULL, por lo que produce el mismo resultado queCOUNT(*). Evite
SELECT * FROM t. Especifique únicamente las columnas que necesita para evitar devolver datos innecesarios.Evite devolver conjuntos de resultados grandes a los clientes de base de datos, salvo en operaciones de extracción, transformación y carga (ETL). Si una consulta devuelve un conjunto de resultados anormalmente grande, compruebe si su plan de ejecución es óptimo.
Para consultas por rango, utilice tipos de datos Range con índices GiST para mejorar el rendimiento.
Si su aplicación ejecuta frecuentemente consultas que devuelven muchas filas, agrupe los resultados en lotes. Por ejemplo, si una consulta devuelve 100 filas, agréguelas en un solo conjunto de resultados. Si su aplicación accede a los resultados por ID, agréguelos periódicamente por ID. Los conjuntos de resultados más pequeños reducen el tiempo de respuesta.
Gestión de instancias
Habilite la función SQL Explorer and Audit para consultar y exportar información sobre la ejecución de SQL, incluidas las bases de datos consultadas, el estado de ejecución y las duraciones. Utilice esta función para diagnosticar el estado del SQL, solucionar problemas de rendimiento y analizar el tráfico. Para obtener más información, consulte Use the SQL Explorer and Audit feature on an ApsaraDB RDS for PostgreSQL instance.
Para monitorear y registrar la actividad dentro de su cuenta de Alibaba Cloud —incluyendo accesos desde la consola, API y herramientas de desarrollo— utilice ActionTrail. ActionTrail registra estas acciones como eventos que puede descargar desde la consola de ActionTrail o enviar a Logstores de Log Service o buckets de Object Storage Service (OSS) para análisis de seguridad, seguimiento de cambios en recursos o auditorías de cumplimiento. Para obtener más información, consulte What is ActionTrail?.
Revise todas las operaciones DDL antes de ejecutarlas y programe los cambios DDL durante horas de baja demanda.
Antes de confirmar transacciones que eliminen o modifiquen datos, ejecute una sentencia
SELECTpara confirmar las filas afectadas. Si su lógica de negocio requiere actualizar exactamente una fila, agregueLIMIT 1.-
Para operaciones DDL y otras operaciones que adquieren bloqueos —como
VACUUM FULLyCREATE INDEX— establezca un tiempo de espera de bloqueo para evitar que bloqueen consultas indefinidamente:BEGIN; SET LOCAL lock_timeout = '10s'; -- DDL statement; END; -
Utilice
EXPLAIN ANALYZEpara inspeccionar el plan de ejecución de una consulta. A diferencia deEXPLAIN,EXPLAIN ANALYZEejecuta realmente la consulta. Si el plan involucra operaciones DML (UPDATE, INSERT o DELETE), envuelva la sentencia en una transacción y reviértala después de la inspección para evitar cambios no deseados en los datos:BEGIN; EXPLAIN (ANALYZE) <DML (UPDATE/INSERT/DELETE) SQL>; ROLLBACK; Para eliminaciones o actualizaciones a gran escala, procese los datos en lotes, cada uno en su propia transacción. Eliminar o actualizar todas las filas en una sola transacción genera grandes cantidades de datos obsoletos.