53.redis分布式缓存

目录

一、单机安装Redis。

二、Redis主从集群。

2.1.集群结构

2.2.准备实例和配置

2.3.启动

2.4.开启主从关系

2.5.测试

三、搭建哨兵集群。

3.1.集群结构

3.2.准备实例和配置

3.3.启动

3.4.测试

四、搭建分片集群。

4.1.集群结构

4.2.准备实例和配置

4.3.启动

4.4.创建集群

4.5.测试

五、单点redis的问题。

六、Redis持久化。

1)RDB持久化。

2) AOF持久化。

3)RDB和AOF的对比。

七、Redis主从。

1)搭建主从架构。

2) 主从数据同步原理。

2.1)全量同步

2.2)增量同步

2.3)优化redis主从集群

2.4)总结

八、Redis哨兵。

1)哨兵的作用和原理。

2)搭建哨兵集群。

3)RedisTemplate的哨兵模式。

九、Redis分片集群。

1)搭建分片集群。

2)散列插槽。

3)集群伸缩。

4)故障转移。

4.1) 自动故障转移。

4.2)手动故障转移。 

5)RedisTemplate访问分片集群。


一、单机安装Redis。

首先需要安装Redis所需要的依赖:

yum install -y gcc tcl

然后将Redis安装包上传到虚拟机的任意目录:

例如,我放到了/tmp目录:

解压缩:

tar -xvf redis-6.2.4.tar.gz

解压后:

进入redis目录:

cd redis-6.2.4

运行编译命令:

Make 工具在执行编译时,会根据 Makefile 文件中的规则来确定编译的位置。Makefile 文件是一个文本文件,其中包含了一系列的规则和指令,用于描述编译的过程。(redis-6.2.4里面有Makefile文件,所以可以使用make指令编译)

在 Linux 操作系统中,通常的软件安装方式是源代码编译安装

make && make install

如果没有出错,应该就安装成功了。

然后修改redis.conf文件中的一些配置:

# 绑定地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问 
bind 0.0.0.0 
# 数据库数量,设置为1 
databases 1

启动Redis:

redis-server redis.conf

远程连接linux系统,然后允许redis的客户端redis-cli。

redis-cli

停止redis服务:

redis-cli客户端中 shutdown 的作用是向 Redis 服务器发送关闭命令,用于优雅地停止 Redis 服务器的运行。

$ redis-cli
127.0.0.1:6379> shutdown

关闭redis服务的时候,会默认先执行RDB持久化,然后再关闭服务。

二、Redis主从集群。

2.1.集群结构

我们搭建的主从集群结构如图:

共包含三个节点,一个主节点,两个从节点。

这里我们会在同一台虚拟机中开启3个redis实例,模拟主从集群,信息如下:

IPPORT角色
192.168.150.1017001master
192.168.150.1017002slave
192.168.150.1017003slave

2.2.准备实例和配置

要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。

1)创建目录

我们创建三个文件夹,名字分别叫7001、7002、7003:

# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003

如图:

2)恢复原始配置(这里是单机安装改动的,所以才需要改回来)

修改redis-6.2.4/redis.conf文件,将其中的持久化模式改为默认的RDB模式,AOF保持关闭状态。

# 开启RDB
# save ""
save 3600 1
save 300 100
save 60 10000

# 关闭AOF
appendonly no

3)拷贝配置文件到每个实例目录

然后将redis-6.2.4/redis.conf文件拷贝到三个目录中(在/tmp目录执行下列命令):

# 方式一:逐个拷贝
cp redis-6.2.4/redis.conf 7001
cp redis-6.2.4/redis.conf 7002
cp redis-6.2.4/redis.conf 7003
# 方式二:管道组合命令,一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp redis-6.2.4/redis.conf

4)修改每个实例的端口、工作目录

修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(在/tmp目录执行下列命令):s是替换,g是全局即符合的全部修改。's/6379/7001/g'表示将文件中所有的"6379"替换为"7001",而's/dir .//dir /tmp/7001//g'表示将文件中所有的"dir ./"替换为"dir /tmp/7001/"。

sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.conf

5)修改每个实例的声明IP(IP地址是按自己主机改)

虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:

# redis实例的声明 IP
replica-announce-ip 192.168.150.101

每个目录都要改,我们一键完成修改(在/tmp目录执行下列命令):(IP地址是按自己主机改)

# 逐一执行
sed -i '1a replica-announce-ip 192.168.150.101' 7001/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7002/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7003/redis.conf

# 或者一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.150.101' {}/redis.conf

2.3.启动

为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:

# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf

启动后:

如果要一键停止,可以运行下面命令:

printf '%s\n' 7001 7002 7003 | xargs -I{} -t redis-cli -p {} shutdown

2.4.开启主从关系

现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。

有临时和永久两种模式:

  • 修改配置文件(永久生效)

    • 在redis.conf中添加一行配置:slaveof <masterip> <masterport>

  • 使用redis-cli客户端连接到redis服务后,执行slaveof命令(重启后失效):

    slaveof <masterip> <masterport>

注意:在5.0以后新增命令replicaof,与salveof效果一致。

这里我们为了演示方便,使用方式二。

通过redis-cli命令连接7002,执行下面命令:(IP地址是按自己主机改)

作用是:7002作为7001的从节点。

# 连接 7002
redis-cli -p 7002
# 执行slaveof
slaveof 192.168.150.101 7001

通过redis-cli命令连接7003,执行下面命令:(IP地址是按自己主机改)

作用是:7003作为7001的从节点。

# 连接 7003
redis-cli -p 7003
# 执行slaveof
slaveof 192.168.150.101 7001

然后连接 7001节点,查看集群状态:

# 连接 7001
redis-cli -p 7001
# 查看状态
info replication

结果:

2.5.测试

执行下列操作以测试:

  • 利用redis-cli连接7001,执行set num 123

  • 利用redis-cli连接7002,执行get num,再执行set num 666

  • 利用redis-cli连接7003,执行get num,再执行set num 888

可以发现,只有在7001这个master节点上可以执行写操作,7002和7003这两个slave节点只能执行读操作。

三、搭建哨兵集群。

注意: 该哨兵集群基于主从集群部署的(因为监控的是主从集群)。

3.1.集群结构

这里我们搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群。如图:

三个sentinel实例信息如下:

节点IPPORT
s1192.168.150.10127001
s2192.168.150.10127002
s3192.168.150.10127003

3.2.准备实例和配置

要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。

我们创建三个文件夹,名字分别叫s1、s2、s3:

# 进入/tmp目录
cd /tmp
# 创建目录
mkdir s1 s2 s3

如图:

然后我们在s1目录创建一个sentinel.conf文件,添加下面的内容:(记得改ip地址)

port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"

解读:

  • port 27001:是当前sentinel实例的端口

  • sentinel monitor mymaster 192.168.150.101 7001 2:指定主节点信息

    • mymaster:主节点名称,自定义,任意写

    • 192.168.150.101 7001:主节点的ip和端口

    • 2:选举master时的quorum值

然后将s1/sentinel.conf文件拷贝到s2、s3两个目录中(在/tmp目录执行下列命令):

# 方式一:逐个拷贝
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3
# 方式二:管道组合命令,一键拷贝
echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf

修改s2、s3两个文件夹内的配置文件,将端口分别修改为27002、27003:

sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf

3.3.启动

为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:

# 第1个
redis-sentinel s1/sentinel.conf
# 第2个
redis-sentinel s2/sentinel.conf
# 第3个
redis-sentinel s3/sentinel.conf

启动后:

3.4.测试

尝试让master节点7001宕机,查看sentinel日志:

查看7003的日志:

查看7002的日志:

四、搭建分片集群。

4.1.集群结构

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

IPPORT角色
192.168.150.1017001master
192.168.150.1017002master
192.168.150.1017003master
192.168.150.1018001slave
192.168.150.1018002slave
192.168.150.1018003slave

4.2.准备实例和配置

删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:

# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003

在/tmp下准备一个新的redis.conf文件,内容如下:

port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下:

# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

4.3.启动

因为已经配置了后台启动模式,所以可以直接启动服务:

# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

通过ps查看状态:

ps -ef | grep redis

发现服务都已经正常启动:

如果要关闭所有进程,可以执行命令:

ps -ef | grep redis | awk '{print $2}' | xargs kill

或者(推荐这种方式):

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

4.4.创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

1)Redis5.0之前

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

# 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群:

# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

2)Redis5.0以后

我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令

  • create:代表是创建集群

  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的样子:M代表master,S代表slave

这里输入yes,则集群开始创建:

通过命令可以查看集群状态:

redis-cli -p 7001 cluster nodes

在Redis集群中,每个节点都会存储整个集群的节点信息,因此连接到一个节点后就可以通过执行cluster nodes命令来获取整个集群的节点信息。

redis-cli -p 7001 cluster nodes命令的含义是通过 Redis 客户端命令行工具连接到端口号为 7001 的 Redis 服务器,并发送cluster nodes命令以获取该 Redis 集群中所有节点的详细信息。

4.5.测试

尝试连接7001节点,存储一个数据:

# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1

结果悲剧了:

集群操作时,需要给redis-cli加上-c参数才可以:

redis-cli -c -p 7001

这次可以了:

五、单点redis的问题。

六、Redis持久化。

1)RDB持久化。

RDB全称Redis Database Backup fileRedis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

快照文件称为RDB文件,默认是保存在当前运行目录。

 

Redis停机时会执行一次RDB

Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格式如下:

RDB的其它配置也可以在redis.conf文件中设置:

服务停止时:就是save操作。

save 60 1000:这种就是bgsave操作。

RDB的持久化:每次都是把内存全部写一遍。

2) AOF持久化。

        AOF是异步的写入aof文件(开启子进程来操作)。

        AOF是记录命令,等下次恢复的时候执行AOF文件的命令就能恢复回来。只记录修改的,查看的不加(如get name等命令不会记录)。

        如果还未触发对key的重写,则AOF文件中或许有多个同key的命令(通过执行bgrewriteaof命令,可以让AOF文件执行重写功能)。

禁用RDB:

AOF效果查看:该截图没有触发重写功能,所以多次set同一个key也会记录下来(恢复数据时后面覆盖前面)。

附录:执行命令的图是只截图一部分,而AOF文件则是全部截图了。

执行重写功能后效果:

3)RDB和AOF的对比。

七、Redis主从。

1)搭建主从架构。

具体操作请看前面。

从节点只能读操作,不能写操作。

假设有A、B两个Redis实例,如何让B作为A的slave节点?

•  B 节点执行命令: slaveof A IP A port

2) 主从数据同步原理。

2.1)全量同步

在没有成为从节点时,每个节点都是master节点,所以都有自己的Replication Id,如果Replication Id不相同,则为第一次同步

简述全量同步的流程?

slave 节点请求增量同步
master 节点判断 replid ,发现不一致,拒绝增量同步
master 将完整内存数据生成 RDB ,发送 RDB slave
slave 清空本地数据,加载 master RDB
master RDB 期间的命令记录在 repl_baklog ,并持续将 log 中的命令发送给 slave
slave 执行接收到的命令,保持与 master 之间的同步

2.2)增量同步

2.3)优化redis主从集群

无磁盘复制就是直接发送到网络(原本是写入磁盘RDB文件后,再将RDB文件发出去)

提示:上面的结构图后面两个slave节点把它前面的slave节点当主节点。

2.4)总结

简述全量同步和增量同步区别?

全量同步: master 将完整内存数据生成 RDB ,发送 RDB slave 。后续命令则记录在 repl_baklog ,逐个发送给 slave
增量同步: slave 提交自己的 offset master master 获取 repl_baklog 中从 offset 之后的命令给 slave

什么时候执行全量同步?

slave 节点第一次连接 master 节点时
slave 节点断开时间太久, repl_baklog 中的 offset 已经被覆盖时

什么时候执行增量同步?

slave 节点断开又恢复,并且在 repl_baklog 中能找到 offset

•  slave 节点宕机恢复后可以找 master 节点同步数据,那 master 节点宕机怎么办?
因为其他slave节点一直跟master同步,master宕机后只需要选一个slave当master即可,宕机节点恢复后变成slave节点。这个过程哨兵机制来操作。

八、Redis哨兵。

1)哨兵的作用和原理。

总结:

Sentinel的三个作用是什么?

监控
故障转移
通知

Sentinel如何判断一个redis实例是否健康?

每隔 1 秒发送一次 ping 命令,如果超过一定时间没有相向则认为是主观下线
如果大多数 sentinel 都认为实例主观下线,则判定服务下线

故障转移步骤有哪些?

首先选定一个 slave 作为新的 master ,执行 slaveof no one
然后让所有节点都执行 slaveof master
修改故障节点配置,添加 slaveof master

2)搭建哨兵集群。

具体操作请看前面部署部分。

3)RedisTemplate的哨兵模式。

读写分离配置:
@SpringBootApplication
public class RedisDemoApplication {
    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
        return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
    }
    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }
}
微服务会与所有节点都建立连接。
为什么配置文件中指定了在 Redis Sentinel 中被监控的主节点名称为 mymaster?
因为在搭建哨兵集群的时候,我们指定了主节点的名称。 redis.sentinel.master配置指定的是在Redis Sentinel中被监控的主服务器的名称。这个名称是在Redis Sentinel配置文件中定义的,用于标识被监控的主服务器。在Spring Boot中,通过指定这个名称,可以让应用程序知道它需要连接哪个被监控的主服务器。
访问微服务效果:
微服务从sentinel(sentinel从master节点)中获取全部节点的ip地址和信息:

九、Redis分片集群。

1)搭建分片集群。

搭建集群请看前面。

2)散列插槽。

效果:根据操作的插槽跳到不同ip地址的redis客户端

总结:

Redis如何判断某个key应该在哪个实例?

16384 个插槽分配到不同的实例
根据 key 的有效部分计算哈希值,对 16384 取余
余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个Redis实例?

这一类数据使用相同的有效部分,例如 key 都以 { typeId } 为前缀
使用了{a}num后有效部分就是a了,这样相同有效部分就不需要重定向了。

3)集群伸缩。

案例1:

操作:

1.创建7004目录,并且复制一份redis.conf到7004中。

2.修改端口为7004,把7004节点添加到集群中。

redis-cli --cluster add-node 192.168.203.129:7004 192.168.203.129:7001 命令添加的是一个新的主节点。它会从指定的源节点(IP 地址为 192.168.203.129,端口号为 7001)获取集群的信息,并将新节点添加到集群中。

3.该命令会重新分配插槽。(需要填写具体信息)

填写要转移的插槽数量:3000

填写转移到的节点的ID:75d7c8436ffb5c4cb225223f41c12bf66e8f85b3(7004节点的ID)

添加转移插槽的源节点:30ddf8b0216fb34e19405cb37d0edfff8f1c6086(7001节点ID)

填完源节点后输入done结束:done

问你是否确定要转移插槽:

4.可以看到7001节点已经把3000个的插槽移到7004节点上。

4)故障转移。

4.1) 自动故障转移。

watch redis-cli -p 7001 cluster nodes     #动态查看集群状态

使用shutdown命令让7002下线后,从节点8003变成主节点:

slave字段后面跟着主节点ID,master后面是ID的。

7002节点恢复后变成从节点:

从这里可以看出来,分片集群自动具备这种主从故障切换的功能。

4.2)手动故障转移。 

手动故障转移:

使用cluster failover后从节点变成主节点,主节点变成从节点。

案例:

效果如下:

5)RedisTemplate访问分片集群。

Lettuce 是一个高性能、可伸缩的 Redis 客户端。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/215148.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络层之SDN基本概念、路由算法和路由协议

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

淘宝API接口申请指南

一、申请条件数据接口 已注册淘宝账号并完成实名认证&#xff1b;拥有良好的淘宝信用记录&#xff1b;符合淘宝API接口的相关规定。 二、申请流程 登录淘宝账号&#xff0c;进入“卖家中心”页面&#xff1b;点击“我要开店”-“申请应用”&#xff0c;选择“淘宝API”&…

LangChain(0.0.340)官方文档五:Model

LangChain官网、LangChain官方文档 、langchain Github、langchain API文档、llm-universe 文章目录 一、Chat models1.1 Chat models简介1.2 Chat models的调用方式1.2.1 环境配置1.2.2 使用LCEL方式调用Chat models1.2.3 使用内置Chain调用Chat models 1.3 缓存1.3.1 内存缓存…

【Linux】:线程(一)概念

线程概念 一.线程1.简单理解2.一些疑问3.简单说一下优缺点&#xff0c;异常和用途 二.进程VS线程1.进程和线程的联系和区别2.phread线程库(创建)3.线程的LWP4.线程等待5.线程终止 三.C11里的线程四.创建线程最底层接口 一般教程里定义线程&#xff1a;是进程内的一个执行分支。…

PicoScope 7 软件报警功能可实现自动保存和循环捕捉

最近很多用户提到&#xff0c;怎么让虹科Pico示波器采集信号到缓冲区满了之后自动保存在电脑里&#xff0c;然后清出缓存空间继续采集&#xff0c;如此循环工作。这里不得不向大家介绍一下PicoScope软件的强大功能之一&#xff1a;报警功能&#xff01; 报警在软件的工具菜单下…

盘点最近两个世纪那些搞怪又精彩的专利

人类的创新是无止境的&#xff0c;下面收集的就是最近两个世纪全球那些奇怪搞笑、精彩的6项专利。 小胡子卫士 (1876) 这款“胡须防护罩”由 VA.Gates 于 1876 年获得专利&#xff0c;是在节日盛宴期间保护胡须的巧妙解决方案。“弯曲和凹形的护罩&#xff0c;可以由硫化橡胶、…

visual c++ 2019 redistributable package

直接安装下面包只有24M Microsoft Visual C Redistributable 2019 x86: https://aka.ms/vs/16/release/VC_redist.x86.exe x64: https://aka.ms/vs/16/release/VC_redist.x64.exe ———————————————— 版权声明&#xff1a;本文为CSDN博主「kpacnB_Z」的原创文章…

堆排序(C语言)

前言 在上一篇内容&#xff1a;大小堆的实现&#xff08;C语言&#xff09;&#xff0c;我们实现了关于创建大小堆的各函数与实现。但是如果突然要使用一个堆排序但是此时并没有一个现成的堆&#xff0c;这就需要花费时间去新建实现堆的插入删除这些操作从而实现一个堆&#xf…

Oracle-CDB容器数据库修改service_names踩坑

前言: 最近在对一套Oracle容器数据库进行迁移测试时&#xff0c;为了保持新环境与旧环境的服务名一致&#xff0c;需要在新环境添加旧环境的服务名&#xff0c;在CDB的根容器通过service_name参数添加旧环境的服务名之后&#xff0c;发现数据库PDB的服务名全部被注销&#xff0…

今日思考 -- 创新领导力(CIO)读后感

收获3个观点&#xff1a; 1 &#xff0c;IT DT 商业&#xff0c;才是未来IT人的出路之一 &#xff01; 2 &#xff0c;在CXO中&#xff0c;CIO像CEO一样&#xff0c;具备了整个企业的业务全视角 &#xff0c;同时也更具解决 ‘’系统性‘’问题的能力 &#xff01; 3 &…

go并发编程(中)

目录 一、并发安全性 1.1 变量并发安全性 1.2 容器并发安全性 二、多路复用 三、协程常见的面试题 3.1交替打印奇数偶数 一、并发安全性 1.1 变量并发安全性 这个和C中并发安全是一样的&#xff0c;主要是多个线程对临界资源的同时访问&#xff0c;最经典的就是 n操作…

网络层之IP数据报格式、数据报分片、IPv4、子网划分和子网掩码

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

openmmlab环境搭建及模拟kitti数据集跑pointpillars模型

点云训练—openmmlab环境搭建及模拟kitti数据集跑pointpillars模型 1 环境搭建 在我的 linux 服务器上&#xff0c;基于ubuntu20.04 参见&#xff1a;开始你的第一步 — MMDetection3D 1.3.0 文档 1.1 本地环境已安装anaconda. anaconda的安装参见博文&#xff1a;DS6.1-Y…

Linux 基本语句_14_信号灯实验

原理&#xff1a; Send进程通过建立共享内存区域&#xff0c;并向其中写入数据&#xff0c;Recive通过与共享内存连接读取其中的数据。 但是如果进程进行读取操作的时候其他进程再次写入会产生数据丢失&#xff0c;产生竞态&#xff0c;为了确保在某段时间内只有一个操作&…

Leetcode—1038.从二叉搜索树到更大和树【中等】

2023每日刷题&#xff08;四十九&#xff09; Leetcode—1038.从二叉搜索树到更大和树 算法思想 二叉搜索树的中序遍历&#xff08;左根右&#xff09;结果是一个单调递增的有序序列&#xff0c;我们反序进行中序遍历&#xff08;右根左&#xff09;&#xff0c;即可以得到一…

基于Java SSM框架实现母婴儿用品网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现母婴儿用品网站系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 母婴用品网站&#xff0c;主要的模块包括管理员&#xff1b;主页、个人中心、用户管理、商品分…

wireshark自定义协议插件开发

目录 脚本代码 报文显示 脚本代码 local NAME "test" test_proto Proto("test", "test Protocol") task_id ProtoField.uint16("test.task_id", "test id", base.DEC) cn ProtoField.uint8("test.cn", &qu…

数学建模-数据新动能驱动中国经济增长的统计研究-基于数字产业化和产业数字化的经济贡献测度

数据新动能驱动中国经济增长的统计研究-基于数字产业化和产业数字化的经济贡献测度 整体求解过程概述(摘要) 伴随着数据要素化进程的不断加深&#xff0c;对于数据如何作用于经济发展&#xff0c;数据与其他要素结合产生的动能应该如何测度的研究愈发重要。本文将数据新动能分…

最热门超声波清洗机有哪些?热门超声波清洗机推荐

眼镜党朋友第一次接触超声波清洗机应该是在眼镜店的时候&#xff0c;把眼镜拿给老板他几分钟就搞定眼镜清洗的&#xff0c;是的没有错&#xff0c;那个机器叫超声波清洗机&#xff0c;不需要自己动手就可把眼镜清洗干净的一款智能清洁工具&#xff0c;它的出现可以说是方便了我…

计算机网络扫盲(4)——时延

一、概述 在这里&#xff0c;我们考虑分组交换网的情况&#xff0c;因特网可以被看成是一种基础设施&#xff0c;该基础设施为运行在端系统上的分布式应用提供服务。在理想情况下&#xff0c;我们希望因特网服务能够在任意两个端系统之间随心所欲地移动数据而没有任何数据地丢失…