¿Por qué Redis es rápido?
Redis se usará en el proyecto, porque redis se puede usar como caché y puede procesar 10w de datos por segundo al mismo tiempo. Pero, ¿sabe por qué el acceso a redis es tan rápido? Se podría decir que redis se basa en la memoria, en el almacenamiento de KV, de un solo hilo ... Espera, ¿por qué el subproceso único es más rápido?
De hecho, Redis es un modelo de multiplexación basado en NIO. En el entorno Windows, es la multiplexación de select, y en el entorno Linux es la multiplexación de epoll. Algunas personas pueden preguntar qué es la multiplexación.
Multiplexación
En pocas palabras, Redis pasa la lectura de datos al kernel para hacer
Multiplexación
Redis pondrá n conexiones de cliente en una colección (aquí hay un proceso), y luego llamará a epoll (no existe tal función en Windows) o seleccionará la función para poner la colección en el kernel del kernel del sistema operativo para su procesamiento, impulsada por eventos, El kernel obtendrá la conexión con los datos y los leerá cíclicamente La complejidad de tiempo es O (1).
Si preguntas qué es NIO? Necesita conocimientos adicionales de NIO.
Estructura de valor de Redis
5 estructuras comunes
estructura de valor
escenas que se utilizarán
Cuerda
Por ejemplo, la cuenta oficial de WeChat puede usar el valor de String para contar el número de lecturas
|
|
Puede ser el número de serie global del sistema distribuido
|
|
consejos: puede usar el comando setnx + timeout para hacer bloqueos distribuidos. Hay un proyecto sobre mi bloqueo distribuido redis en github: dislock
Además de que redis se puede usar como un bloqueo distribuido, zookeeper también se puede usar como un bloqueo distribuido (basado en el nombre de nodo único y el mecanismo de observador). Comparado con redis, zookeeper es más fuerte que redis en consistencia final, pero su rendimiento será más débil que redis. proyecto de bloqueo distribuido de github: distributionlock
Mapa de bits
Puede contar cuántas veces ha iniciado sesión el usuario en cualquier período de tiempo
El mapa de bits es una matriz binaria de longitud ilimitada (cuando la longitud es de 2 mil millones, ocupa más de 200 MB de memoria). El valor de la matriz es 0 o 1. Como se muestra en la figura anterior, si el usuario sean inicia sesión el cuarto día, es
|
|
Inicie sesión el día 9 como
|
|
Y así. La última línea cuenta el número de veces que el valor es 1 entre el primer índice y el último índice.
También podemos usar mapa de bits para contar el número de usuarios activos
|
|
consejos: el famoso filtro Bloom se puede implementar con mapa de bits
Picadillo
hash puede almacenar información relacionada con el carrito de compras
Como se muestra arriba: la identificación del usuario es la clave, la identificación del producto se archiva y la cantidad del producto se almacena como valor. Puede mostrar información del carrito de compras.
|
|
La estructura hash tiene las siguientes ventajas y desventajas:
ventaja
1) Almacenamiento consolidado de datos similares, conveniente para la gestión de datos
2) En comparación con la operación de cadenas, consume menos memoria y cpu
3) En comparación con el almacenamiento de cadenas, ahorra más espacio
Desventaja
1) La función de vencimiento no se puede usar en el campo, sino solo en la clave.
2) La arquitectura del clúster de Redis no es adecuada para uso a gran escala
En general, el hash se puede utilizar para almacenar la agregación de páginas de detalles y los datos provienen de la agregación de diferentes bibliotecas.
Lista
La lista se puede utilizar como una estructura de datos, como colas, pilas, etc.
Escenarios de mensajes de Weibo y mensajes de cuentas oficiales
|
|
Lista de operaciones comunes
|
|
Conjunto
El juego se puede utilizar como un mini programa de lotería WeChat.
|
|
También se puede usar para Me gusta de WeChat y Weibo
|
|
El modelo de atención de Weibo y WeChat se puede realizar mediante operaciones colectivas
|
|
establecer operaciones comunes
|
|
En general, el conjunto se puede utilizar para deduplicación, lotería y otras operaciones.
Zset
zset es un conjunto ordenado de deduplicación, que se puede utilizar para implementar clasificaciones
Resumen: zset se puede utilizar en escenarios como tablas de clasificación y cambio de página. Zset se puede usar como una cola de retraso, la puntuación es el punto de tiempo de retraso, el valor del puerto se obtiene secuencialmente al obtenerlo y se puede quitar si la marca de tiempo actual es igual a la puntuación.
La estructura de datos subyacente de zset es una tabla de salto, una lista vinculada especial, que es excelente para buscar, agregar y eliminar. Para obtener conocimientos específicos, consulte el artículo:
GEO
redis también puede admitir consultas de ubicación geográfica, adecuadas para el desarrollo LBS
Comandos comunes
Corriente
La nueva estructura "Stream" comenzó en Stream 5.0. Escenario de uso: escenario de productor consumidor (similar a MQ)
Comandos comunes
Ejemplo
|
|
Ahora, redis se usa comúnmente en 3.x, y las listas también se pueden usar para colas de mensajes. Muy poca gente usa Stream.
Clúster de Redis
Para la construcción de clústeres, consulte: Construcción de clústeres Redis3.0
Preocupaciones sobre el clúster
1、增加了slot槽的计算,是不是比单机性能差?
共16384个槽,slots槽计算方式公开的,HASH_SLOT=CRC16(key)mod16384。
为了避免每次都需要服务器计算重定向,优秀的java客户端都实现了本地计算,并且缓存服务器slots分配,有变动时再更新本地内容,从而避免了多次重定向带来的性能损耗。
2、redis集群大小,到底可以装多少数据?
理论是可以做到16384个槽,每个槽对应一个实例,但是redis官方建议是最大1000个实例。存储足够大了。
3、ask和moved重定向的区别
重定向包括两种情况
a.若确定slot不属于当前节点,redis会返回moved。
b.若当前redis节点正在处理slot迁移,则代表此处请求对应的key暂时不在此节点,返回ask,告诉客户端本次请求重定向。
4、数据倾斜和访问倾斜的问题
倾斜导致集群中部分节点数据多,压力大。解决方案分为前期和后期:前期是业务层面提前预测,哪些key是热点,在设计的过程中规避。后期是slot迁移,尽量将压力分摊(slot调整有自动rebalance、reshard和手动)。
5、读写分离
redis cluster默认所有从节点上的读写,都会重定向到key对接槽的主节点上。
可以通过readonly设置当前连接可读,通过readwrite取消当前连接的可读状态。
注意:主从节点依然存在数据不一致的问题
Redis可用性
通过主从集群实现高可用,slave节点向master节点发送syn请求同步命令。master节点会通过bgsave命令创建rdb文件将数据以二进制形式存储其中,然后将文件分发给slave节点。
tips: 1.bgsave是创建了子线程工作,不影响主线程; 2.主从结构以线性链表部署,不要图状结构部署
Redis缓存失效问题
缓存一致性模型
查询信息时,先从缓存中获取信息;缓存中没有则从数据库中获取;将值塞到缓存。
缓存击穿
查询一个不存在的key,查询会直接落到数据库上。如果黑客用不存在的key查询,很可能搞垮数据库。
解决思路:查询之前先判断目标数据是否存在,不存在的直接忽略。将流量拦截于缓存和数据库之前。
这里使用布隆过滤器:
布隆过滤器
demo示例:
|
|
布隆过滤器优缺点
优点:
内存空间占用少
缺点:
布隆过滤器需要不断维护,带来新的工作
布隆过滤器并不能精准过滤。(布隆过滤器判定不存在,100%不存在,判断为存在,则可能不存在的。)理论上Hash计算值是有碰撞的(不同的内容hash计算出同样的值),导致不存在的元素可能
会被判断为存在
为了减少hash碰撞,可以将key用几个hash算法获取index值。然而布隆过滤器并非需要拦截所有的请求,只需要将缓存击穿控制在一定的量即可。
缓存雪崩
当大量的key在统一时间过期,而这时又有大量的访问key,请求落到数据上,导致数据库崩溃。
解决办法:
Semaphore信号量限流
J.U.C包重要的并发编程工具类,又称“信号量”,控制多个线程争抢许可。
核心方法
acquire:获取一个许可,如果没有就等待,
release:释放一个许可。
典型场景
1、代码并发处理限流;
示例:
|
|
容错降级
如果令牌被抢完(并发时还没来的及释放令牌),线程执行到这里时可以返回一个异常码。
redis集群方案
还有一种可能,如果redis key来不及删除,由于内存淘汰策略。会删除一些key,导致缓存失效。集群方案可以解决内存不足问题。
高并发下缓存不一致问题
根据缓存一致性模型:
查询信息时,a.1:先从缓存中获取信息;a.2:缓存中没有则从数据库中获取;a.3:将值塞到缓存。
更新数据时,b.1:更新数据库;b.2:删除缓存
如果查询和更新是两个线程,由于以上执行并非原子性,b.2可能会先于a.3执行。导致redis里面数据和数据库数据不一致。
解决方法
可以先将数据预热到redis中,去掉查询时存入redis的操作。再部署一个mysql服务,收集mysql日志。数据库数据发生变化的时候,通知缓存维护程序,把变化后的数据更新到到缓存里面。
关于数据库监听,阿里有一套开源框架 Canal ,可以监听mysql的数据变化。
Redis持久化
1.RDB快照:将数据以二进制形式写到文件中
2.AOF:将写命令以追加的形式写入到aof文件中
关于aof有下面几种形式:
a. redis没操作一次,写一次文件。优点是保证完整性,缺点是一致性会下降
b. 每秒钟将写命令写入到一个buffer中,当buffer中存满一定的数据,再写入到文件中(aof默认采用此种写入)
c.每次操作将写命令存入buffer中,之后再写入文件中
使用
默认是使用rdb恢复数据,如果开启aof,重启之后会加载aof文件恢复。当然生产环境上是混合使用。比如8点之前我使用rdb恢复,8点之后我使用aof恢复。
往期推荐
扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料
1.回复"java" 获取java电子书;
2.回复"python"获取python电子书;
3.回复"算法"获取算法电子书;
4.回复"大数据"获取大数据电子书;
5.回复"spring"获取SpringBoot的学习视频。
6.回复"面试"获取一线大厂面试资料
7.回复"进阶之路"获取Java进阶之路的思维导图
8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)
9.回复"总结"获取Java后端面试经验总结PDF版
10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)
11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)
另:点击【我的福利】有更多惊喜哦。