诺安科技
约 1061 字大约 4 分钟
2026-04-04
数据库和redis信息怎么保持一致
1.先更新缓存,在更新数据库:
2.先更新数据库,再更新缓存
3.先删除缓存,再更新数据库,再缓存新数据
4.先更新数据库,再删除缓存,再缓存新数据
5.缓存双删:先删除缓存,再更新数据库,再延迟删除缓存
6.binlog异步更新缓存
保证实时一致性:先更新数据库,再删除缓存,短期数据不一致
保证最终一致性:先更新数据库,在binlog+消息队列
保证强一致性:
分布式读写锁

写操作:
- 获取写锁(检查是否有写锁或读锁)
- 更新数据库
- 删除缓存
- 释放写锁
读操作:
- 获取读锁(检查是否有写锁).
- 查询缓存:如果命中缓存,释放读锁,返回结果。如果未命中,读取数据库,并将数据更新到缓存。
- 释放读锁
kafak消息拥堵
遇到的场景:一个数据点位有两个数采地址,每次只有一个地址有数据;通过另一个参数来确认取哪一个的值,刚好这个参数的值是空,取不到数据,导致kafka消息无法手动确认,消息就堵死了;
监控图形上就只展示到前10分钟之前的图形数据,就不动了
groups命令查询消息偏移数量
kafka保证消息不丢失,重复消费
生产者:
消息不丢失:
确保消息写入所有副本(acks=all)
发送失败可以重试
重复消费:
开启幂等性
消费者:
消息不丢失:
手动提交偏移量
重试
重复消费:
保证多次消费消息相同
kafka自动确认机制
确认模式类型:
- RECORD: 每处理一条消息提交一次
- BATCH: 每处理一批消息提交一次
- TIME: 按时间间隔提交
- COUNT: 按消息数量提交
- COUNT_TIME: 按时间或数量提交,先到先提交
- MANUAL: 手动提交
- MANUAL_IMMEDIATE: 手动立即提交
es 100w索引设计
比如日志信息,怎么设计索引,肯定不能都在一个索引上
根据时间动态创建索引,每天或者每月
es和数据库的数据同步
logstash配置文件
关键字
input,filter,output
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.
input {
jdbc {
jdbc_driver_library => "C:\Users\Administrator\AppData\Roaming\JetBrains\DataGrip2021.1\jdbc-drivers\MySQL ConnectorJ\8.0.25\mysql\mysql-connector-java\8.0.25\mysql-connector-java-8.0.25.jar"
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://localhost:3306/xiaofei_site_search"
jdbc_user => "root"
jdbc_password => "root"
use_column_value => true
tracking_column => "updateTime"
tracking_column_type => "timestamp"
parameters => { "isDelete" => 1 }
schedule => "*/5 * * * * *"
jdbc_default_timezone => "Asia/Shanghai"
# 记录上次执行位置
last_run_metadata_path => "D:/tools/Elastic_Search/logstash-7.17.12/data/plugins/last_run_metadata_file"
statement => "
SELECT
id,
fileName,
description,
file_type as fileType,
file_extension as fileExtension,
file_content as textContent,
description,
upload_time as uploadTime,
upload_user_id as uploadUserId,
biz,
is_public as isPublic,
created_at as createdAt,
updated_at as updatedAt,
status as status
FROM file where upload_time > :sql_last_value and upload_time < now() order by upload_time desc
"
}
}
filter{
mutate {
rename => {
"file_name" => "fileName"
"file_path" => "filePath"
"file_type" => "filetype"
"file_extension" => "fileExtension"
"file_content" => "textContent"
"upload_time" => "uploadTime"
"upload_user_id" => "uploadUserId"
"is_public" => "isPublic"
"created_at" => "createdAt"
"updated_at" => "updatedAt"
"description" => "description"
"status" => "status"
}
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => "127.0.0.1:9200"
index => "file_v1"
document_id => "%{id}"
}
}hibernate 二三级缓存
一次缓存:session关联;查询实体时优先查询
二级缓存:sessionFactory关联,跨越多个session;一级缓存没有时,查询并将查询结果存入二级缓存,数据更新、删除、新增时二级缓存同步更新
三级缓存(查询缓存):查询结果存储在查询缓存
查询数据的过程:
- 先查一级缓存(Session) ↓ 未命中
- 再查二级缓存(SessionFactory) ↓ 未命中
- 最后查询缓存(Query Cache) ↓ 未命中
- 查询数据库
// Hibernate使用CacheKey类来标识缓存对象
public class CacheKey {
private final String entityName; // 实体类名
private final Serializable identifier; // 主键值
private final EntityMode entityMode; // 实体模式
private final String tenantId; // 租户ID(如果有)
// 示例
@Entity
public class User {
@Id
private Long id; // identifier
private String name;
// entityName = "com.example.User"
// identifier = id值
}
}一级缓存使用EntityKey作为key
EntityKey = entityName + id + entityMode
二级缓存key组成:
regionName + key
regionName默认是实体类全限定名
key是CacheKey对象
查询缓存key组成:
查询SQL
查询参数值
首个返回行数
当前使用的Filters
贡献者
更新日志
fb8bc-更新为vuepress于