那些你可能不知道的 ZooKeeper 知识
nanshan 2024-10-22 12:54 10 浏览 0 评论
本文作者:HelloGitHub-老荀
Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源、有趣、入门级的 ZooKeeper 教程,面向有编程基础的新手。
项目地址:https://github.com/HelloGitHub-Team/HelloZooKeeper
今天我要介绍些 ZK 的隐藏功能,废话不多,让我们开始吧~
一、JMX
JMX(Java Management Extensions,即 Java 管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX 可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活地开发无缝集成的系统、网络和服务管理应用。
是不是听不懂?听不懂就对了,如果你从来没有开发过 JMX 或者应用过的话,我这里就简单介绍下:JMX 就是 Java 提供的一个标准,这个标准可以将一些有需要的 Java 对象运行时的状态暴露出去(这些对象可以叫 MBean),一般是用于监控或者运行时修改一些配置信息。
我们既然是讲解 ZK,那么我现在就有问题了,现在我手里有一个简单 ZK 集群正在运行,我想知道哪个节点是 Leader,怎么办?
首先 ZK 本身在启动的时候就会主动将一些对象注册成为 MBean,而我们直接使用 Java 自带的工具 jconsole 就能查看,下面我演示下,我这里有一个简单的 ZK 集群:
nbsp;jps
5266 QuorumPeerMain
2964
10438 Jps
4550 Launcher
5286 QuorumPeerMain
5767 JConsole
5388 QuorumPeerMain
9215 Launcher
可以看到有三个 QuorumPeerMain 的进程,就代表了这个集群的三个节点。
下面我们使用 jconsole 打开该工具(安装了 jdk,这个工具就自动拥有了)
nbsp;jconsole
随便选择一个 ZK 的进程,选择连接即可。
JMX 不光光可以看对象的属性也可以执行一些方法,比如:
图中显示操作的地方都是可以在右侧找到一个按钮进行调用的(还可以传参),关于 ZK 中 JMX 更多的细节,我这里暂时不披露了,之后有机会单独讲解,反正大家只需要知道 JMX 就是将一些普通 Java 对象暴露出去,可以通过工具查看属性或者调用该对象的方法的一个标准。
二、四字命令 与 Admin Server
刚刚那个 JMX 查看还是比较麻烦的,因为现在我们测试访问的是我本地的进程,如果是远程的 JVM 进程,用 jconsole 访问起来就更麻烦了,有没有简单一点的方法。肯定是有!ZK 本身支持了一些四字命令(4lw)用于和服务端进行交互。
我这里做一个简单的演示,我本地的集群的客户端端口分别是:2181、2182、2183,我通过 telnet 命令随便连接上一个节点:
nbsp;telnet localhost 2181
Trying ::1...
Connected to localhost.
Escape character is '^]'.
就会进入交互模式,然后输入 srvr 按下回车,就能得到以下输出
nbsp;telnet localhost 2181
Trying ::1...
Connected to localhost.
Escape character is '^]'.
srvr
Zookeeper version: 3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715, built on 09/04/2020 12:44 GMT
Latency min/avg/max: 0/3.8261/44
Received: 30
Sent: 29
Connections: 1
Outstanding: 0
Zxid: 0x100000009
Mode: leader
Node count: 6
Proposal sizes last/min/max: 48/48/94
Connection closed by foreign host.
srvr 命令就是用来查看服务节点的状态的,从输出中的 Mode 字段就能看到,监听 2181 端口的这个节点就是 Leader,我们再换一个 2182 节点看看,Mode 就是 Follower。
nbsp;telnet localhost 2182
Trying ::1...
Connected to localhost.
Escape character is '^]'.
srvr
Zookeeper version: 3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715, built on 09/04/2020 12:44 GMT
Latency min/avg/max: 0/0.0/0
Received: 3
Sent: 3
Connections: 1
Outstanding: 0
Zxid: 0x100000009
Mode: follower
Node count: 6
Connection closed by foreign host.
这里要提一下默认的四字命令不是全部打开的,如果想要启用所有的四字命令需要在环境变量中指定 zookeeper.4lw.commands.whitelist=*,也可以通过列出具体的命令(逗号分隔)来启用指定的一些四字命令。我们再换个命令看看吧,比如 envi,就会输出当前节点的环境参数
java.io.tmpdir=/var/folders/19/bx8xsqgd1c78g5j1mt_zq5v80000gp/T/
java.compiler=<NA>
os.name=Mac OS X
os.arch=x86_64
os.version=10.16
user.name=junjiexun
user.home=/Users/junjiexun
user.dir=/Users/junjiexun/develop/zk
os.memory.free=101MB
os.memory.max=889MB
os.memory.total=123MB
我这里列一下所有的四字命令的作用,具体就不演示了,留给读者自己尝试吧,官网四字命令列表,四字命令其实就是它右边命令的别名而已,作用是完全一样的。(* 依旧表示 TODO,之后开篇单讲)
我还看到了 ruok,用来查看服务器节点是否启动(能成功返回不代表能对外提供服务 )
除了通过 telnet 方式去调用 ZK 提供的四字命令,ZK 还提供了一个更友好的方式就是 Admin Server。
ZK 在启动后,默认会监听本机的 8080 端口并启动一个 Jetty 容器作为 Web 服务器,如果访问该端口下的 /commands 路径的话会得到:
直接访问这些超链接就可以拥有和之前四字命令一样的效果~也可以直接在 URL 上访问 ip:port/commands/<commandName>。
以 mntr为例,可以直接访问 http://localhost:8080/commands/mntr 或者 http://localhost:8080/commands/monitor 都是一样的。
因为 Admin Server 默认就是启用的,而且接受来自任何 IP 的请求,为了安全考虑的话可以通过配置环境变量 zookeeper.admin.serverAddress=10.3.54.12,类似这样增加请求的 IP 的要求或者直接通过 zookeeper.admin.enableServer=false 禁用 Admin Server。
ZK 官方是推荐直接使用 Admin Server 的,来替代命令行的四字命令的,基于这些官方的接口是可以做一些 ZK 监控平台的。
三、动态配置
ZK 的集群配置一般都是在启动的时候通过读取配置文件,之后就不会再变更了,并且如果我要为集群添加一个新的节点,需要修改配置文件再重启方才能生效的。
但是在 3.5.0 之后, ZK 更新了动态配置的功能,集群的配置不再需要停机重新配置,可以在运行时直接修改,可以直接为集群增删节点,修改他们的角色,甚至可以修改集群的计票规则!是不是碉堡了!
3.1 计票规则
在此之前,我先介绍下 ZK 支持的两种计票规则。
3.1.1 过半机制
这是 ZK 默认的计票规则,用于各种服务端集群需要 ACK 的场景,假设现在的配置是这样:
server.1=zoo1:2888:3888:participant
server.2=zoo2:2888:3888:participant
server.3=zoo3:2888:3888:participant
server.4=zoo4:2888:3888:observer
server.5=zoo5:2888:3888:observer
因为 Observer 是不会算入选票的,实际参与的机器是前三个节点:1、2、3
先不管 Leader 是谁,默认的计票规则需要这三个节点中的至少两个成功提交 ACK(或是其他需要计票的信息),这个选举(或者提案)才能被继续提交,这就是过半机制。
3.1.2 分组权重
ZK 还提供了一个新的计票规则,这个规则支持将各个节点分成不同的组(当然也可以只有一个组),同一个组中的不同节点也可以被分配成不同的权重,我举个例子:
group.1=1:2:3
group.2=4:5:6:7:8
group.3=9
weight.1=1
weight.2=1
weight.3=1
weight.4=1
weight.5=1
weight.6=1
weight.7=1
weight.8=1
weight.9=1
group 开头和 weight 开头分别对应了分组和权重的配置,规定如下:
- group 的格式是 group.<groupId>=<serverId>:<serverId>...
- weight 的格式是 weight.<serverId>=<weight>
- serverId 就是每一个服务节点配置在 myid 中的数字
- 每一个节点只能属于一个 group
那以我现在配置的情况继续说明的话,现在一共有三个 group,分别的权重计算如下 :
group1 的权重总和 = server1 的权重 + server2 的权重 + server3 的权重 = 1 + 1 + 1 = 3
group2 的权重总和 = server4 的权重 + server5 的权重 + server6 的权重 + server7 的权重 + server8 的权重= 1 + 1 + 1 + 1 + 1 = 5
group3 的权重总和 = server9 的权重 = 1
假如现在成功 ACK 的服务节点有 1、4、5、8、9 并以这样的配置进行计票的话
- 首先看 group1 只有 server1 成功回复 ACK,权重值为 1,并未超过 group1 权重总和 3 一半以上,所以 group1 相当于 ACK 失败了
- 再看 group2 有 4、5、8 三个节点成功回复 ACK,权重值为 3,超过了 group2 权重总和 5 的一半以上(3 > 5/2),所以 group2 ACK 成功
- 然后看 group3,因为只有一个节点 9,并成功回复 ACK,所以也满足了超过 group3 权重总和 1 的一半以上(1 > 1/2),所以 group3 ACK 成功
- 最后统计成功 ACK 的 group 数量是否超过整体 group 数量的一半以上,现在有 2 个 group 成功 ACK(2 > 3/2) ,所以最终 ACK 通过
感觉看起来和默认的过半机制差不多,No,No,No。我这里看起来差不多的原因是因为我把权重都设置成了 1,如果设置成别的数字呢?
刚刚的场景中只有 group1 的 ACK 最终失败了,原因是因为只有 server1 一个节点成功回复,但是如果我把 group1 的权重改成(另外两个 group 省略了)
group.1=1:2:3
weight.1=3
weight.2=1
weight.3=1
现在 group1 的权重总和变成了 3 + 1 + 1 = 5,server1 的权重是 3 了,就算只有它一个节点回复了,也超过了 group1 的一半以上(3 > 5/2),如果是此时的权重配置的话,group1 也是算作成功 ACK 的。
还有必须要说明的一点,在 ZK 读取这些配置的时候就会计算每一个 group 的权重总和,如果计算出来某一个 group 的权重总和是 0,则该 group 被移除出计票规则中了。
和默认的过半机制不同的是,使用权重配置的话,是可以让 Observer 参与的。
3.2 推荐配置
说了半天,怎么启用这个权重的计票规则呢?
- (推荐)在 zoo.cfg 中配置 dynamicConfigFile 选项用来指定动态配置的路径地址,将所有的 server 、group 和 weight 开头的配置都移至该路径的配置文件中。
- 将所有的 server 、group 和 weight 开头的配置都直接配置在 zoo.cfg 文件中
只要在配置文件中被 ZK 发现有 group 或者 weight 开头的配置,就表示启用权重的计票规则,否则使用默认的过半机制。
我们之前的 server 前缀配置是这样:
server.1=zoo1:2888:3888:participant
实际的 server 配置的格式应该是这样的,可以将客户端的端口配置在 server 配置中的(最后的分号后面)
server.1=zoo1:2888:3888:participant;2181
如果这样配置的话,zoo.cfg 中就不需要配置 clientPort 选项了。
所以按照推荐的配置方式的话,zoo.cfg 就配置这些(路径请根据读者的电脑自行调整)
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/Users/junjiexun/develop/zk/zk01/data
dynamicConfigFile=/Users/junjiexun/develop/zk/zk01/conf/zoo.dyn.cfg
...
而我在 /Users/junjiexun/develop/zk/zk01/conf/zoo.dyn.cfg 的文件中就可以配置
server.10000000000=127.0.0.1:2888:3888:participant;2181
server.2=127.0.0.1:2887:3887;2182
server.3=127.0.0.1:2886:3886;2183
group.1=10000000000:2:3
weight.10000000000=1
weight.2=1
weight.3=1
更详细的可以查看官方文档
3.3 动态修改
那么问题来了,我这样配置好了后,怎么才能动态地往集群中添加节点或者删除节点呢?
Java 的客户端提供了一个 getConfig 的方法
ZooKeeper client = new ZooKeeper("127.0.0.1:2181", 3000, null);
byte[] config = client.getConfig(false, null);
System.out.println(new String(config));
client.close();
打印出来的结果是
server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182
server.3=127.0.0.1:2886:3886:participant;0.0.0.0:2183
server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181
group.1=2:3:10000000000
weight.2=1
weight.3=1
weight.10000000000=1
version=0
这些信息看起来和我们配置的 zoo.dyn.cfg 有点像但是又有点不一样,不一样的地方实际就是 ZK 帮我们自动补齐的格式,而这个返回的数据 ZK 是存在哪里的呢?ZK 在启动的时候默认会在根路径创建以下节点
/
|--zookeeper
|--config
|--quota
而 getConfig 返回的数据实际就是 /zookeeper/config 节点的数据,而且这个节点的权限只有 Read,不信你用 getData 试试,返回的数据是一样的
ZooKeeper client = new ZooKeeper("127.0.0.1:2181", 3000, null);
byte[] config = client.getData("/zookeeper/config", false, null);
System.out.println(new String(config));
client.close();
现在可以获取到这个配置了,那怎么去修改呢?ZK 官方提供了两种方式:命令行、Java API。
如果使用 Java 内置的命令行工具,在支持的命令中就有一个 reconfig 命令,参数是:
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
另一种就是使用 Java 的客户端代码,我们之前一直使用的是 ZooKeeper 这个类,他还有一个子类叫 ZooKeeperAdmin,这个子类就拥有 reconfigure 方法可以对配置进行修改,下面我来演示下,但在此之前我必须说明下动态修改配置的特性
- 动态修改配置分为:增量和非增量的方式
- 因为实际上修改的就是 /zookeeper/config 节点的数据,而这个节点默认只有 Read 权限,所以要么直接使用管理员权限进行修改操作,要么就在环境变量中配置 zookeeper.skipACL=yes 跳过 ACL 的校验
- 使用增量方式修改配置的时候,集群的计票规则必须是过半机制!
- 使用非增量的方式修改配置时,两种机制均可。
- 将 Follower 从集群配置中删除,只是相当于把它降级为 Observer,它是仍然可以对外提供服务端,并且也同样可以接受到 Leader 的消息
- 将 Leader 从集群配置中删除时,会造成较大的性能影响,整个集群在选出新的 Leader 之前是无法对外提供服务的,请尽量不要这么做
- 而增加节点就轻松很多,新加入的节点会自动和 Leader 进行同步数据
3.3.1 增量删除节点
假设我现在一共有 3 个节点,采用的是过半机制(必须得是),三个 ID 分别是 10000000000、2、3,我们尝试将 ID 为 3 的节点删除,我这里采用直接配置 skipACL 跳过权限校验(下同)
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null);
List<String> leavingServers = new ArrayList<>();
leavingServers.add("3");
byte[] reconfigure = client.reconfigure(null, leavingServers, null, -1, null);
System.out.println(new String(reconfigure));
client.close();
该接口返回的数据就是 /zookeeper/config 修改完成后的配置信息,可以看到新的配置中和 3 有关的数据就消失了
server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182
server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181
version=400000004
这个 version=400000004 是干嘛的呢?ZK 为修改的配置默认也提供了版本的控制,启动成功后会在你配置的 dynamicConfigFile 路径下自动生成一个文件,我这里是 zoo.cfg.dynamic.300000000 读者可能跟我的不一样。这个 300000000 就是版本号,而当我把 ID 为 3 的节点删除后,ZK 又自动生成了个文件 zoo.cfg.dynamic.400000004 这个 400000004 就是新的版本号,如果我们在修改的时候对当前集群配置的版本号有要求的话就可以在 reconfigure 方法中的第四个参数填入需要的目标版本号即可,我例子中是 -1 代表无视版本号,和 delete、setData 的 version 字段是一个用意。
3.3.2 增量增加节点
让我们再把节点 3 加回去
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null);
List<String> joiningServers = new ArrayList<>();
joiningServers.add("server.3=127.0.0.1:2886:3886;2183");
byte[] reconfigure = client.reconfigure(joiningServers, null, null, -1, null);
System.out.println(new String(reconfigure));
client.close();
得到的新配置内容是
server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181
server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182
server.3=127.0.0.1:2886:3886:participant;0.0.0.0:2183
version=400000013
节点 3 加回去了,而且版本号又改变了,又多了一个 zoo.cfg.dynamic.400000013 文件
3.3.3 非增量
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null);
List<String> newMembers = new ArrayList<>();
newMembers.add("server.10000000000=127.0.0.1:2888:3888:participant;2181");
newMembers.add("server.3=127.0.0.1:2886:3886;2183");
byte[] reconfigure = client.reconfigure(null, null, newMembers, -1, null);
System.out.println(new String(reconfigure));
client.close();
这样的话相当于把 ID 为 2 的节点给删除了(当然也可以新增节点,我这里就不演示了)
3.4 小节
三种不同的方式实际对应的就是 Java API 的三个参数 joiningServers、leavingServers、newMembers,而且 Java API 参数除了使用 List 还可以使用 String(逗号分隔)也可以达到同样的效果。动态增删服务节点让我们可以在避免停机的前提下调整整个 ZK 集群的服务能力(个人觉得动态增加比较有用)。
而分组权重的计票规则提供了一种新的归票策略,特别是配合动态配置,可以运行时修改权重,但总体来说,分组权重的计票规则比较鸡肋,我也不知道能在什么样的场景下使用(高性能的机器可以权重大一点?问题是现在都是云服务,容器化和虚拟化的,机器的配置都可以动态调整的,而且一般机器配置也都是一样的,实在是想不到还有什么用)
如果读者有关于分组权重的使用思路可以分享给大家噢~关于更多的动态配置可以参考 官方文档
四、ZK 监控
ZK 3.6 之后新增的 Metrics 是 ZK 提供给用户可查询的监控指标,官网上也说了可以结合 Prometheus 或者 Grafana 来使用。什么?你完全没用过,甚至没听说过!那巧了这两个东西我也没玩过,借着这个机会就和大家一起学习下,搞个 Hello World,不过因为本系列是以 ZK 为主的,所以一切从简配置,Let's GO!
4.1 Prometheus
Mac 安装特别简单,其他平台可以去官网下载压缩包
nbsp;brew install prometheus
我这里的默认安装路径是 /usr/local/Cellar/prometheus/2.23.0
在此之前还需要在 ZK 节点的配置 zoo.cfg 加两行
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
metricsProvider.httpPort=7000
我是本地起的三个节点,另外两个节点需要改成 7001 和 7002,因为端口不能重复
之后修改 Prometheus 的默认配置,在我的电脑上路径为 /usr/local/etc/prometheus.yml 修改为
global:
scrape_interval: 15s
scrape_configs:
- job_name: "test-zk"
static_configs:
- targets: ["localhost:7000", "localhost:7001", "localhost:7002"]
job_name 可以随便起,重点是 targets 目标地址和 scrape_interval 访问间隔,修改完毕后,就可以启动 Prometheus
nbsp;cd /usr/local/Cellar/prometheus/2.23.0
nbsp;./bin/prometheus --config.file=/usr/local/etc/prometheus.yml
然后访问 localhost:9090 就能看到如下界面了:
只要勾上了 Enable autocomplete 就可以在输入框里输入了,马上就能得到提示,我这里随便输几个参数看看
简单的就演示到这里了,剩下的交给读者了~
4.2 Grafana
Mac 安装 Grafana 也非常简单
nbsp;brew install grafana
安装完毕后,可以通过命令启动
nbsp;grafana-server --config=/usr/local/etc/grafana/grafana.ini --homepath /usr/local/share/grafana --packaging=brew cfg:default.paths.logs=/usr/local/var/log/grafana cfg:default.paths.data=/usr/local/var/lib/grafana cfg:default.paths.plugins=/usr/local/var/lib/grafana/plugins
Grafana 默认的端口是 3000,访问 localhost:3000 默认的用户名密码均是 admin,就能看到首页了
Grafana 天然支持了 Prometheus 的数据源,可以直接添加
默认的配置只需要修改 URL(默认是 localhost:9090)
然后需要添加一个 dashboard 的模板,ZK 官方给我们提供了一个模板,贴心吧
10465 这个数字哪儿来的呢?官方文档的模板
大功告成!比 Prometheus 好看多了~
关于 ZK 的监控就介绍到这里了。传统功夫,点到为止~
五、ZK 可视化开源项目介绍
使用命令行操作 ZK 太麻烦了,所以可视化就很有必要了,下面推荐几个不错的可视化客户端,有的是本地客户端,有的是 Web 服务,大家按需获取吧~
- PrettyZoo:可视化 GUI 客户端,各个平台都有安装文件,需要连接 ZK 服务端的时候,手边有这样一个工具还是很方便的
- zkdash:JavaScript + Python 可视化 Web 客户端,是个可以直接运行的 Web 服务,缺点是 Python2.7 开发的,如果不需要二次开发的话就没什么问题
- zoonavigator-web:TypeScript 编写的可视化 Web 客户端,是个可以直接运行的 Web 服务
- visual-zookeeper:Electron + React 编写的客户端
相关推荐
- 实战派 | Java项目中玩转Redis6.0客户端缓存
-
铺垫首先介绍一下今天要使用到的工具Lettuce,它是一个可伸缩线程安全的redis客户端。多个线程可以共享同一个RedisConnection,利用nio框架Netty来高效地管理多个连接。放眼望向...
- 轻松掌握redis缓存穿透、击穿、雪崩问题解决方案(20230529版)
-
1、缓存穿透所谓缓存穿透就是非法传输了一个在数据库中不存在的条件,导致查询redis和数据库中都没有,并且有大量的请求进来,就会导致对数据库产生压力,解决这一问题的方法如下:1、使用空缓存解决对查询到...
- Redis与本地缓存联手:多级缓存架构的奥秘
-
多级缓存(如Redis+本地缓存)是一种在系统架构中广泛应用的提高系统性能和响应速度的技术手段,它综合利用了不同类型缓存的优势,以下为你详细介绍:基本概念本地缓存:指的是在应用程序所在的服务器内...
- 腾讯云国际站:腾讯云服务器如何配置Redis缓存?
-
本文由【云老大】TG@yunlaoda360撰写一、安装Redis使用包管理器安装(推荐)在CentOS系统中,可以通过yum包管理器安装Redis:sudoyumupdate-...
- Spring Boot3 整合 Redis 实现数据缓存,你做对了吗?
-
你是否在开发互联网大厂后端项目时,遇到过系统响应速度慢的问题?当高并发请求涌入,数据库压力剧增,响应时间拉长,用户体验直线下降。相信不少后端开发同行都被这个问题困扰过。其实,通过在SpringBo...
- 【Redis】Redis应用问题-缓存穿透缓存击穿、缓存雪崩及解决方案
-
在我们使用redis时,也会存在一些问题,导致请求直接打到数据库上,导致数据库挂掉。下面我们来说说这些问题及解决方案。1、缓存穿透1.1场景一个请求进来后,先去redis进行查找,redis存在,则...
- Spring boot 整合Redis缓存你了解多少
-
在前一篇里面讲到了Redis缓存击穿、缓存穿透、缓存雪崩这三者区别,接下来我们讲解Springboot整合Redis中的一些知识点:之前遇到过,有的了四五年,甚至更长时间的后端Java开发,并且...
- 揭秘!Redis 缓存与数据库一致性问题的终极解决方案
-
在现代软件开发中,Redis作为一款高性能的缓存数据库,被广泛应用于提升系统的响应速度和吞吐量。然而,缓存与数据库之间的数据一致性问题,一直是开发者们面临的一大挑战。本文将深入探讨Redis缓存...
- 高并发下Spring Cache缓存穿透?我用Caffeine+Redis破局
-
一、什么是缓存穿透?缓存穿透是指查询一个根本不存在的数据,导致请求直接穿透缓存层到达数据库,可能压垮数据库的现象。在高并发场景下,这尤其危险。典型场景:恶意攻击:故意查询不存在的ID(如负数或超大数值...
- Redis缓存三剑客:穿透、雪崩、击穿—手把手教你解决
-
缓存穿透菜小弟:我先问问什么是缓存穿透?我听说是缓存查不到,直接去查数据库了。表哥:没错。缓存穿透是指查询一个缓存中不存在且数据库中也不存在的数据,导致每次请求都直接访问数据库的行为。这种行为会让缓存...
- Redis中缓存穿透问题与解决方法
-
缓存穿透问题概述在Redis作为缓存使用时,缓存穿透是常见问题。正常查询流程是先从Redis缓存获取数据,若有则直接使用;若没有则去数据库查询,查到后存入缓存。但当请求的数据在缓存和数据库中都...
- Redis客户端缓存的几种实现方式
-
前言:Redis作为当今最流行的内存数据库和缓存系统,被广泛应用于各类应用场景。然而,即使Redis本身性能卓越,在高并发场景下,应用于Redis服务器之间的网络通信仍可能成为性能瓶颈。所以客户端缓存...
- Nginx合集-常用功能指导
-
1)启动、重启以及停止nginx进入sbin目录之后,输入以下命令#启动nginx./nginx#指定配置文件启动nginx./nginx-c/usr/local/nginx/conf/n...
- 腾讯云国际站:腾讯云怎么提升服务器速度?
-
本文由【云老大】TG@yunlaoda360撰写升级服务器规格选择更高性能的CPU、内存和带宽,以提供更好的处理能力和网络性能。优化网络配置调整网络接口卡(NIC)驱动,优化TCP/IP参数...
- 雷霆一击服务器管理员教程
-
本文转载莱卡云游戏服务器雷霆一击管理员教程(搜索莱卡云面版可搜到)首先你需要给服务器设置管理员密码,默认是空的管理员密码在启动页面进行设置设置完成后你需要重启服务器才可生效加入游戏后,点击键盘左上角E...
你 发表评论:
欢迎- 一周热门
-
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
[常用工具] OpenCV_contrib库在windows下编译使用指南
-
WindowsServer2022|配置NTP服务器的命令
-
Ubuntu系统Daphne + Nginx + supervisor部署Django项目
-
WIN11 安装配置 linux 子系统 Ubuntu 图形界面 桌面系统
-
解决Linux终端中“-bash: nano: command not found”问题
-
Linux 中的文件描述符是什么?(linux 打开文件表 文件描述符)
-
NBA 2K25虚拟内存不足/爆内存/内存占用100% 一文速解
-
K3s禁用Service Load Balancer,解决获取浏览器IP不正确问题
-
- 最近发表
-
- 实战派 | Java项目中玩转Redis6.0客户端缓存
- 轻松掌握redis缓存穿透、击穿、雪崩问题解决方案(20230529版)
- Redis与本地缓存联手:多级缓存架构的奥秘
- 腾讯云国际站:腾讯云服务器如何配置Redis缓存?
- Spring Boot3 整合 Redis 实现数据缓存,你做对了吗?
- 【Redis】Redis应用问题-缓存穿透缓存击穿、缓存雪崩及解决方案
- Spring boot 整合Redis缓存你了解多少
- 揭秘!Redis 缓存与数据库一致性问题的终极解决方案
- 高并发下Spring Cache缓存穿透?我用Caffeine+Redis破局
- Redis缓存三剑客:穿透、雪崩、击穿—手把手教你解决
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)