selección de la tecnología de bloqueo distribuido

En primer lugar, basado en la aplicación de bloqueo de base de datos distribuida

  1. bloqueo pesimista

Uso seleccione ... donde ... para la actualización de bloqueo exclusivo

Nota: Otras características adicionales consistentes con una realización, a destacar aquí es "donde nombre = bloqueo", nombre de campo de índice debe ir, de lo contrario, se bloqueará la tabla. En algunos casos, tales como mesas pequeñas, optimizador de MySQL no se irá el índice, lo que resulta en un problema de bloqueo de la tabla.

  1. El bloqueo optimista

El llamado frente de bloqueo optimista y la mayor diferencia es que el pensamiento basado en la CAS, que no tiene mutuamente excluyentes, sin espera de bloqueo mientras que el consumo de recursos durante la operación no cree que hay una violación de concurrencia sólo después de la versión de actualización no percibió. Nuestra compra, pico es utilizar esta aplicación para evitar el exceso de ventas.
Bloqueo optimista consigue aumentando el campo de número de versión incrementa

En segundo lugar, sobre la base de la memoria caché (Redis, etc.) para lograr bloqueo distribuido

  1. Utilice los comandos:
    (1) SETNX
    SETNX val clave: si y sólo si no existe la clave, una clave SET es una cadena de val, devuelve 1; si la clave está presente, entonces no hacer nada, se devuelve 0.
    (2) El expiran
    El tiempo de espera expiran Clave: Establecer un tiempo de espera para la clave, la unidad es el segundo, más de este tiempo se liberará automáticamente la cerradura, para evitar estancamiento.
    (3) la Eliminar
    la tecla de borrado: tecla Supr

Cuando se utiliza la aplicación de bloqueos Redis distribuidas, serán utilizados principalmente para estos tres comandos.

  1. Pensamiento logra:
    (1) cuando la adquisición de la cerradura, uso setnx bloqueo, y utilizar el comando para agregar un tiempo de espera expira el tiempo de la cerradura, el tiempo más allá del cual libera automáticamente el bloqueo, el bloqueo es un valor del UUID generado de forma aleatoria, en esta versión bloqueo hora de juzgar.
    (2) para obtener un bloqueo, cuando se puso un tiempo de espera adquirido durante este tiempo si usted renuncia a adquirir el bloqueo.
    (3) cuando se libera el bloqueo, no es determinado por el UUID de la cerradura, si el bloqueo, el bloqueo se libera durante el borrado.

  2. Distribuido código de implementación sencilla de bloqueo:

Copiar código
1 / *
2 * distribuido código de implementación sencilla de bloqueo 4. /
5 DistributedLock {public class.
6.
7 final privado JedisPool jedisPool;.
. 8
. 9 DistributedLock pública (JedisPool jedisPool) {
10 = this.jedisPool jedisPool;
. 11}
12 es
13 es /
*
14 * bloqueo
15 * bloqueo @param lockName Key
16 * @param adquisición acquireTimeout de tiempo de espera
de tiempo de espera de bloqueo 17 * @param tiempo de espera de
18 * identificador de bloqueo @return
19. /
20 es lockWithTimeout public String (String lockName, acquireTimeout largo, Long tiempo de espera) {
21 es Jedis Conn = null;
22 se retIdentifier cadena = null;
23 es el try {
24 // conectarse
JedisPool.getResource Conn = 25 ();
26 es un generado de forma aleatoria // valor
27 = UUID.randomUUID identificador de cadena () toString () ;.
28 // nombre de bloqueo, es decir, valor de clave
29 Cadena lockKey = "bloqueo:" + lockName;
30 // período de tiempo de espera, después de lo cual el bloqueo se libera automáticamente de la cerradura
31 es lockExpire int = (int) (tiempo de espera / 1000);
32
33 se adquiere // tiempo de espera de bloqueo, durante este tiempo de abstenerse de la adquisición de la cerradura
extremo largo 34 = System.currentTimeMillis () + acquireTimeout;
35 el tiempo (System.currentTimeMillis () <End) {
36 IF (conn.setnx (lockKey, identificador) == 1). {
37 [conn.expire (lockKey, lockExpire);
se devuelve 38 // valor valor para liberar la confirmación de tiempo de bloqueo
39 identificador = retIdentifier;
40 retorno retIdentifier;
41 es}
42 es -1 // no establece el tiempo de espera de clave representativo, una clave conjunto el tiempo de desbordamiento
43 es IF (conn.ttl (lockKey) == -1) {
44 conn.expire (lockKey, lockExpire);
45}
46
47 try {
48 Thread.sleep (10);
49} catch (InterruptedException e) {
50 Thread.currentThread () de interrupción (.);
51}
52}
53} catch (JedisException e) {
54 e.printStackTrace ();
55} finally {
56 si (conn = null) {
57 conn.Close ();
58}
59}
retIdentifier 60 de retorno;
61}
62
63 /
*
64 *释放锁
65 * @param lockName锁的clave
66 * @param identificador释放锁的标识
67 * @return
68 * /
69 releaseLock public boolean (String lockName, String Identificador) {
Jedis Conn = null 70;
71 es lockKey String = "Bloqueo:" + LockName;
72 = false Boolean retFlag;
73 es el try {
74 jedisPool.getResource Conn = ();
75 al mismo tiempo (en true) {
76 // bloqueo del monitor, listo para comenzar una transacción
conn.watch 77 (lockKey);
78 // determinación del valor por el valor devuelto no está en frente de la cerradura, si se retira la cerradura, liberar el bloqueo
79 de IF (identifier.equals (conn.get (lockKey))) {
80 la Transacción conn.multi = Transacción ();
81 transaction.del (lockKey);
82 = transaction.exec Lista de resultados ();
83 SI (resultados == null) {
84 Continuar;
85}
86 = retFlag true;
87}
88 Conn. unwatch ();
89 PAUSA;
90}
91} es la captura (JedisException E) {
92 e.printStackTrace ();
El finalmente {} 93
94 IF (Conn = null) {
95 conn.Close ();
96}
97}
retFlag 98 de retorno;
99}
100}
copiar el código

  1. Test de bloqueo acabo de dar cuenta Distribuido

Ejemplo usando un pico de 50 hilos analógicas producto, que se utiliza - operador para lograr una reducción en el producto, a partir de los resultados de pedidos se pueden ver si el estado bloqueado.

servicio de pico de simulación, donde se puede configurar el grupo de subprocesos jedis, bloqueo distribuido pasó durante la inicialización, para su uso.

Copia el código
de servicio public class {

private static JedisPool pool = null;

private DistributedLock lock = new DistributedLock(pool);

int n = 500;

static {
    JedisPoolConfig config = new JedisPoolConfig();
    // 设置最大连接数
    config.setMaxTotal(200);
    // 设置最大空闲数
    config.setMaxIdle(8);
    // 设置最大等待时间
    config.setMaxWaitMillis(1000 * 100);
    // 在borrow一个jedis实例时,是否需要验证,若为true,则所有jedis实例均是可用的
    config.setTestOnBorrow(true);
    pool = new JedisPool(config, "127.0.0.1", 6379, 3000);
}

public void seckill() {
    // 返回锁的value值,供释放锁时候进行判断
    String identifier = lock.lockWithTimeout("resource", 5000, 1000);
    System.out.println(Thread.currentThread().getName() + "获得了锁");
    System.out.println(--n);
    lock.releaseLock("resource", identifier);
}

}
Copia el código

hilos analógicos pico servicios;

Copiar el código
público de la ThreadA extiende la clase Thread {
Privado-servicio-servicio;

public ThreadA(Service service) {
    this.service = service;
}

@Override
public void run() {
    service.seckill();
}

}

la clase de prueba {public
static void main (String [] args) {
-Servicio-Service-Servicio de noticias nuevos = ();
for (int i = 0; I <50; i ++) {
en ThreadA ThreadA en ThreadA nuevos nuevos = (-Servicio);
threadA.start ( );
}
}
}
copiar el código
resultados siguientes, el resultado se ordenó:

Escribir imágenes describen aquí

Si el comentario fuera parte de un bloqueo:

Copiar el código
público seckill void () {
// devuelve el valor de valor de bloqueo para determinar cuándo liberar un bloqueo
// Cadena Indentifier = lock.lockWithTimeout ( "Recursos", 5000, 1000);
System.out.println (Thread.currentThread ( ) .getName () + "bloqueo obtenido");
System.out.println (-n);
//lock.releaseLock("resource", Indentifier);
}
copiar el código
se puede ver a partir de los resultados, hay algunos asíncrono de:

Escribir imágenes describen aquí

En tercer lugar, sobre la base de la cerradura realización Zookeeper distribuido

ZooKeeper es proporcionar un servicio consistente para aplicaciones distribuidas componentes de código abierto en su interior es una estructura de árbol de directorios del sistema de archivos jerárquico, lo dispuesto en el mismo directorio sólo puede tener un nombre de archivo único. ZooKeeper paso se basa en la aplicación de bloqueo distribuido:

(1) Crear una myLock directorio;
(2) Un hilo quieren obtener un bloqueo en la creación de una orden temporal de los nodos en el directorio myLock;
(3) Obtiene todos los nodos secundarios en el directorio myLock, y luego se hacen más pequeños que sus hermanos, si no hay , entonces el número corriente de secuencia hilo mínimo, para adquirir la cerradura;
(4) de hilo B adquiere todos los nodos, se determina que no son el nodo más bajo, siempre escuchando veces más pequeño que su propio nodo;
(5) el hilo un procesado, eliminar su propio nodo, el hilo B escuchas a los eventos de cambio, determinar si es el nodo más pequeño, si está a continuación, obtener la cerradura.

Se recomienda que una biblioteca de código abierto Apache Conservador, es un cliente ZooKeeper, oferta InterProcessMutex curador es lograr un bloqueo distribuido, adquirir el método utilizado para obtener el bloqueo, el método de liberación para liberar el bloqueo.

Ventajas: se proporciona una alta disponibilidad, por reentrada, bloqueando características cerraduras, insuficiencia resuelven el problema de interbloqueo.

Contras: Debido a la frecuente necesidad de crear y nodos de eliminación, como una forma Redis en el rendimiento.

En cuarto lugar, el contraste

bloqueo de base de datos distribuida para lograr
desventajas:

1.db rendimiento operativo es pobre, y existe el riesgo de bloqueo de la tabla
2. Después de una operación de no bloqueo falla, la necesidad de sondeo, los recursos de CPU de ocupación;
3. mucho tiempo no cometen o sondeo largo, la conexión puede consumir más recursos

Redis (caché) Distributed Lock lograr
desventajas:

1. Eliminar el mal control de bloqueo de caducidad fallido
2 sin bloqueo, la operación falla, la necesidad de sondeo, los recursos de CPU de ocupación;

ZK Distributed Lock lograr
Desventajas: El rendimiento es mejor Redis lograr, debido principalmente a una operación de escritura (para obtener la liberación de bloqueo) necesidad de llevar a cabo en el líder, y luego sincroniza con el seguidor.

En resumen: ZooKeeper un mejor rendimiento y fiabilidad.

Desde la perspectiva de la facilidad apreciado (de bajo a alto) de base de datos> Caché> el Zookeeper

Desde el punto de vista de la aplicación de la complejidad (menor a mayor) Zookeeper> = Cache> Base de datos

Desde un punto de rendimiento (bajo) cachés> Zookeeper> = Base de Datos

Desde el punto de vista de la fiabilidad (mayor a menor) del Zookeeper> Caché> Base de datos

Publicado 33 artículos originales · ganado elogios 0 · Vistas 846

Supongo que te gusta

Origin blog.csdn.net/ninth_spring/article/details/104806617
Recomendado
Clasificación