2008-11-07 9 views
10

¿Cuál es la mejor manera de configurar su piscina con respecto a: -¿Cómo configura su grupo de conexiones?

  1. ¿Cuándo se crea conexiones?
  2. ¿Cuándo cierras las conexiones, y las cierras todas?
  3. ¿Está probando que las conexiones siguen siendo buenas? ¿Cuando y cómo?
  4. ¿Cómo averigua un buen número para la cantidad máxima de conexiones?
  5. ¿Qué tipo de control tiene para garantizar que los usuarios de la agrupación se porten bien? ¿Puedes evitar que un mal código saque todo?
  6. ¿Ha escrito su propio grupo o usado una biblioteca de terceros?

Creo que esta es una pregunta independiente, pero los comentarios sobre "características" de bases de datos/idiomas particulares son bienvenidos. Por ejemplo, puede ser más lento o más costoso conectarse en algunas bases de datos que en otros.

Para aclarar, no tengo la intención de escribir un grupo desde cero, esta pregunta es más acerca de cómo configurar una biblioteca existente que hace la agrupación.

Respuesta

6

Escribí un grupo de conexiones para la base de datos en Java cuando era solo un patrón de diseño y no una biblioteca común. Ahora uso el integrado en Tomcat.

que utiliza un hilo para controlar varios aspectos de la piscina y varios parámetros para controlar su comportamiento ...

  1. minimumInPool = "3" ... Estos tres primeros se crea tras la puesta en marcha. Nunca se permite que la agrupación caiga por debajo de tres.
  2. maximumIdleTimeBeforeRemoval = "60" ... Si una conexión está inactiva durante una hora, suéltela y cree una nueva. El tiempo de inactividad probablemente significa que solo hay un mínimo de tres en el grupo.
  3. maximumInUseTimeBeforeRemoval = "30" ... Si se ha verificado una conexión determinada durante más de 30 minutos, entonces es probable que algo esté mal. Recuérdelo y mate la conexión.
  4. maximumTimeBeforeRemoval = "60" ... Quítelo si tiene más de 60 minutos de antigüedad.
  5. maximumUsageBeforeRemoval = "1000" ... Quítelo si se ha revisado más de 1000 veces.
  6. monitorInterval = "15" ... Compruebe los parámetros anteriores cada 15 minutos.

Esto me ha servido muy bien durante un par de años. Lo más que he visto en la piscina fue 151 conexiones durante un vistazo salvaje. Por lo general, el grupo estaba en alrededor de una docena durante el uso intensivo y estaba inactivo hasta el mínimo de tres en la madrugada.

Utilicé los controladores delgados JDBC de Oracle y los conecté a una base de datos Oracle.

1

¿Por qué reinventar la rueda?

Alguien probablemente ya ha resuelto el problema, y ​​mejor.

Si está en el mundo de Java, puede usar Commons DBCP.

3

Aquí está el razonamiento que utilicé para una implementación reciente.

  1. Tiene dos tipos de conexiones en su grupo de conexiones. El primero está listo, es decir, abierto pero no utilizado por un cliente. El segundo está activo, es decir, en uso por un cliente.

  2. Haga que su agrupación de conexiones mantenga un número pequeño de conexiones listas, un mínimo de N y un máximo de M. N se puede ajustar dependiendo de la velocidad máxima a la que sus clientes soliciten conexiones. Si el número de conexiones listas alguna vez cae a cero, necesita una N. más grande Si el número es constantemente alto (digamos por encima de 10), necesita una menor N.

  3. Cuando un cliente desea una conexión, dele una. de los listos (lo que lo activa), inmediatamente abra uno nuevo si ahora hay menos de N listo (pero no haga que el cliente espere hasta que se complete, o perderá la ventaja de la puesta en común). Esto asegura que siempre habrá al menos N conexiones preparadas. Si ninguno está listo cuando el cliente quiere uno, tendrán que esperar mientras usted crea uno nuevo.

  4. Cuando el cliente finaliza con una conexión activa, regrésela al estado listo si hay menos de conexiones M ready. De lo contrario, ciérralo. Esto le impide tener más de M conexiones preparadas.

  5. Recicle periódicamente las conexiones listas para evitar conexiones obsoletas. Si hay más de N conexiones preparadas, solo cierre la conexión más antigua. De lo contrario, ciérrelo y vuelva a abrir otro.

Esto tiene la ventaja de tener suficiente listos y conexiones juveniles disponibles en su grupo de conexión sin sobrecargar el servidor.

2

No estoy seguro de cuál es el contexto en el que utiliza sus conexiones, pero puedo compartir lo que parece funcionar para mí.

Uso el servidor SQL como mi back-end y uso una combinación de almacenamiento en caché para obtener un mejor rendimiento. Mi práctica es mantener la conexión abierta solo si realmente la necesito y no agrupar conexiones para que se puedan limpiar de inmediato y puedo ver en el Monitor de actividad de SQL exactamente qué está activo y qué no. Cada conexión ocupa memoria, así que es agradable mantenerla en un rugido sordo cuando no se necesitan.

Antes de responder a la pregunta de apertura y cierre de la conexión, permítanme decir que el almacenamiento en caché es realmente importante. Obtener un objeto de la memoria caché le ahorrará un montón de tiempo. En algunas de mis aplicaciones asp.net cuando el almacenamiento en caché está en desarrollo, he descubierto que apenas puedo medir la latencia, mientras que con una llamada al DB puede llevar de 15ms a 45ms completar la llamada y esto ni siquiera está considerando otra latencia factores o carga. El otro método que uso es una buena estructura de objetos para mis datos, de modo que solo realizo una actualización de DB si algo cambia. Implementé algunos métodos en mi objeto o me aseguro de estar haciendo tan poco IO como sea posible.

Una vez dicho esto, todos sabemos que tenemos que acceder y escribir en nuestra base de datos en algún momento, así que seguir dos principios:

  1. mantener las puertas y ventanas cerradas para ahorrar energía. Una conexión abierta en un lugar significa que no está disponible en otro (o la memoria y otros recursos son más limitados).Hemos desactivado la agrupación porque ha resultado en un mejor rendimiento para nosotros.

  2. Hago tanto en lote como a la vez cuando puedo cuando la conexión está abierta. Esto es un poco más complicado, así que déjame explicarte.

    • Un método que he usado es pasar mis objetos de conexión por la tubería para que todos los objetos puedan usar un objeto de conexión. Esto da como resultado que una conexión se abra y se cierre en lugar de tal vez 10 o más según su aplicación. Un buen ejemplo de esto es uno de nuestros modelos de compras que aprovecha el poder del servidor SQL para recopilar estadísticas y organizar patrones de pedidos complicados. No tiene sentido seguir abriendo y cerrando la conexión cuando estás haciendo una búsqueda de 200K + DB o para lo que sean las aplicaciones. La otra parte de esto es que cuando uso el objeto intento agrupar mis actualizaciones para reducir el tiempo que mantengo la conexión abierta. Así que al hacer una scope_identity en la llamada de inserción, vamos a ocuparme tanto de mi inserción como de la búsqueda de la ID única para agregar a mi objeto antes de almacenarlo en la memoria caché. Antes, cuando comencé a desarrollar aplicaciones asp, abría la conexión tan pronto como la página comenzaba a cargarse y luego la cerraba. No recomiendo hacer eso nunca más. Ahora, un día, hay un gran beneficio para este tipo de abstracciones y capas que recomendaría a cualquier programador novato que preste especial atención.

Mis dos centavos:

caché de sus datos! ¡Guarde sus datos en caché! ¡Guarde sus datos en caché! ¡Haga tan poco acceso a la base de datos como sea posible cuando no pueda almacenar en caché y luego almacenar en caché sus datos!

2

Jakarta Commons DBCP ya lo hace todo lo que indicó:

  • crea conexiones según sea necesario y los administra en una piscina
  • puede cerrar las conexiones si no se han utilizado durante un cierto período de tiempo
  • puede ejecutar una consulta en una conexión antes de distribuirla, y si hay un error, la conexión se descarta y se crea una nueva. Las conexiones también se pueden probar periódicamente mientras está inactivo.
  • puede establecer un límite en las conexiones que se crearán y también en el número mínimo de conexiones para tener listo. El límite de curso depende mucho de tu aplicación.
  • No sé cómo pero DBCP sabe cuándo una conexión no se está cerrando y la cierra por usted, lanzando una excepción para que sepa lo que sucedió cuando vea su registro.
  • DBCP tiene un parámetro de tiempo de espera que es muy útil. Si se utilizan todas las conexiones del grupo, esperará ese período de tiempo para que se devuelva una conexión al grupo y si no hay ninguna disponible cuando se alcanza el límite, obtendrá un error.

Puede ajustar su grupo jugando con la cantidad mínima de conexiones, el número máximo de conexiones que se crearán y el tiempo de espera. Un tiempo de espera más largo le permitirá tener un límite inferior de conexiones, mientras que un tiempo de espera más corto probablemente requerirá un número mayor. Esto depende en gran medida de lo que hace su aplicación y cómo utiliza las conexiones.

2

Estoy de acuerdo con matt b en que no debemos reinventar la rueda.

Sin embargo, el uso de Commons DBCP es discutible en función de las respuestas de las preguntas this y this. Hay mejores alternativas mencionadas allí como c3po o proxool.

O puede usar el mecanismo de agrupamiento de conexiones dependiente de rdbms.

Cuestiones relacionadas