当前位置: 首页 > news >正文

Redis: 主从复制原理

主从复制原理剖析


1 )配置

  • 通过下面的从节点的配置项可以开启主从之间的复制功能
    slaveof 192.16.10.101 6379
    
  • 这里的复制包含全量复制和增量复制

2 )主节点的主从配置信息解析

  • 查看主从之间的信息,在主节点上 $ info replication 打印出来的细节
    # Replication
    role: master
    connected_slaves: 2
    slave0:ip=192.168.10.102,port=6379,state=online,offset=2184,lag=1
    slave1:ip=192.168.10.103,port=6379,state=online,offset=2184,lag=1
    master_replid:0e233bbb3b38aada4764b58c2dc9e74ddfc85ccc
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:2184
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen: 2184
    
    • 从节点 offset 是指读取命令的偏移量
      • 相当于: 从节点现在已复制的偏移量的长度
      • 主节点实际上会把所有的命令转成字节,然后写到一个队列里边
      • 然后它写入了多少会记录下最终的值,也就是对应下面的 master_repl_offset
      • 两者相等,表示主从数据一致
    • lag 延迟时间,lag=1 延迟时间是1s,主从同步数据会有延迟
    • master_repl_offset 主节点已写入的命令偏移量
    • master_replid 和 master_replid2
      • master_replid 表示主节点的一个 replicationID, 它是40个16进制的字符串,随机生成的
      • master_replid2
        • 表示主节点的状态发生改变之后
        • 新的主节点ID会存放在 master_replid 中
        • 旧的主节点ID会存放在 master_replid2 中
    • 下面的5项都是在 Redis 2.8 之后, 出现的特性
      • 这里既然涉及到了主从复制,肯定会有一个全量复制,增量复制这样一个概念在里边
      • 全量复制是指:从节点把主节点的数据据全部都拷贝过去
      • 这种一般发生在环境初始化和从节点扩展以及主节点故障在从节点选举新的主节点场景中
      • 在主节点故障重新选举的过程中,run_id 会出现变化, 在 $ info server 命令中就有这个 run_id
      • 从节点根据这个 run_id 来判断是全量复制还是增量复制
    • 在2.8版本之后出现 second_repl_offset 这个配置,还有一个缓冲区的概念
    • 关于 second_repl_offset 这个配置
      • 2.8 之后,全量增量复制多了一个命令,叫 psync, 之前是建立一个 sync 的操作
      • 比如说, 现在主节点故障重启之后,它发现 run_id 变了,二话不说,走一个全量复制
      • 再有,比如说,主节点故障了,重新选取主节点,会把上一次主节点已写入队列的偏移量 master_repl_offset 记录下来,寄存到这个 second_repl_offset
      • 比如现在 master_repl_offset 已经是 2590 了,在存的时候 second_repl_offset 一般做一个 +1 的操作,也就是变成了 2591,这样,从节点再重新跟主节点建立连接的时候,会拿到这个 second_repl_offset
      • 根据上面的情况 second_repl_offset 比 master_repl_offset 多了一个字节,就没有必要做全量复制了
      • 只需要继续保持现状,跟它持续连接,每十秒 ping 一下,监听着它就行了, 继续做增量操作
      • 所以,second_repl_offset 的作用就是为了避免每一次主从的角色改变/故障重启等场景带来可能的全量复制操作而浪费性能,这样增量操作就能解决问题
    • 关于缓冲区的配置
      • repl_backlog_active: 1 表示缓冲区开启
      • repl_backlog_size:1048576 表示缓冲区的大小, 这里是 1M的大小
      • repl_backlog_first_byte_offset:1 表示从1的位置开始写
      • repl_backlog_histlen: 2184 表示当前缓冲区的长度

3 )从节点的主从配置信息解析

  • 在从节点上 $ info replication 打印出来的细节
    # Replication
    role:slave
    master_host:192.168.10.101
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:5
    master_sync_in_progress:0
    slave_repl_offset:2842
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:0e233bbb3b38aada4764b58c2dc9e74ddfc85ccc
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:2842
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:2842
    
  • 上面 master_* 是主节点的一系列信息,主要看下
    • master_last_io_seconds_ago:5 表示从库和主库最后一次同步数据的时间在五秒之前
    • master_sync_in_progress:0 表示和主库的同步状态,0是未同步,1是正在同步
    • master_repl_offset:2842 表示主节点写入的偏移量
  • 上面 slave_* 是从节点的一些列配置
    • slave_repl_offset 表示从节点复制的偏移量,和上面主节点写入偏移量一致,说明同步了
    • slave_priority:100 表示从节点在选举时成为主节点的一个几率
      • 比如主节点宕机,剩下的2个从节点开始参与选举
      • 谁能竞选成功,就看上面这个数值的大小,越大则优先级越高,竞选越容易成功
      • 如果这个值为 0,则这个从节点永远不会变成主节点
    • slave_read_only:1 从节点只读模式,1表示开启,0表示关闭
  • connected_slaves:0 表示连接到从节点的信息
    • 作为从节点,也是可以去连其他的从节点的
  • 其他选项不再赘述

4 ) Master复制日志查看

  • master/slave 进行主从进行复制的时候,在日志中也是可以体现出来

  • 下面通过查看日志的方式,把主从的一个复制流程走一遍

  • 在主节点查看日志:$ tail -f -n 800 /usr/local/redis/log/redis.log, 我们从下面位置来看

    l. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo madvi
    se > /sys/kernel/mm/transparent hugepage/enabled' as root, and add it to your /etc/rc. local in order to retai
    n the setting after a reboot. Redis must be restarted after THP is disabled (set to 'madvise' or 'never').
    1468:M 1 Oct 2020 14:21:15.520 * DB loaded from append only file: 0.000 seconds
    1468:M 1 Oct 2020 14:21:15.520 * Ready to accept connections
    1468:M 1 Oct 2020 14:21:28.323 * Replica 192.168.10.102:6379 asks for synchronization
    1468:M 1 Oct 2020 14:21:28.324 * Full resync requested by replica 192.168.10.102:6379
    1468:M 1 Oct 2020 14:21:28.324 * Replication backlog created, my new replication IDs are '0e233bbb3b38aada47
    64b58c2dc9e74ddfc85ccc'and '0000000000000000000000000000000000000000'
    1468:M 1 Oct 2020 14:21:28.324 * Starting BGSAVE for SYNC with target: disk
    1468:M 1 Oct 2020 14:21:28.324 * Background saving started by pid 1474
    1474:C 1 Oct 2020 14:21:28.326 * DB saved on disk
    1474:C 1 Oct 2020 14:21:28.326 * RDB: 4 MB of memory used by copy-on-write
    1468:M 1 Oct 2020 14:21:28.332 * Background saving terminated with success
    1468:M 1 Oct 2020 14:21:28.332 * Synchronization with replica 192.168.10.102:6379 succeeded
    1468:M 1 Oct 2020 14:21:30.858 * Replica 192.168.10.103:6379 asks for synchronization
    1468:M 1 Oct 2020 14:21:30.858 * Full resync requested by replica 192.168.10.103:6379
    1468:M 1 Oct 2020 14:21:30.858 * Starting BGSAVE for SYNC with target: disk
    1468:M 1 Oct 2020 14:21:30.859 * Background saving started by pid 1475
    1475:C 1 Oct 2020 14:21:30.861 * DB saved on disk
    1475:C 1 Oct 2020 14:21:30.861 * RDB: 4 MB of memory used by copy-on-write
    1468:M 1 Oct 2020 14:21:30.952 * Background saving terminated with success
    1468:M 1 Oct 2020 14:21:30.952 * Synchronization with replica 192.168.10.103:6379 succeeded
    
  • Ready to accept connections 表示随时等待其他节点的连接

  • Replica 192.168.10.102:6379 asks for synchronization 表示 102 从节点开始过来复制了

    • 这里可见,它发起了 sync 的请求
  • Full resync requested by replica 192.168.10.102:6379 表示 102 的复制请求是全量的复制请求

  • Replication backlog created, my new replication IDs are '0e233bbb3b38aada4764b58c2dc9e74ddfc85ccc'and '0000000000000000000000000000000000000000'

    • 刚把环境起起来,这里主节点开始创建缓冲区并生成新的 replication IDs
    • 这里有2个ID,就是上文说的 master_replid 和 master_replid2
  • 下面是RDB的操作

    1468:M 10 Nov 2020 14:21:28.324 * Starting BGSAVE for SYNC with target: disk
    1468:M 10 Nov 2020 14:21:28.324*  Background saving started by pid 1474
    1474:C 10 Nov 2020 14:21:28.326 * DB saved on disk
    1474:C 10 Nov 2020 14:21:28.326 * RDB: 4 MB of memory used by copy-on-write
    1468:M 10 Nov 2020 14:21:28.332 * Background saving terminated with success
    
    • 首先,通过 BGSAVE 把数据写入磁盘,可以看到它是后台的写入进程
    • 之后,通过 copy-on-write 把内存的 4M 数据写入磁盘
    • 最后,保存结束,终止
  • Synchronization with replica 192.168.10.102:6379 succeeded

    • 这里,提示 102 机器的复制成功了
  • 下面是 103 重复RDB的复制操作

    1468:M 10 Nov 2020 14:21:30.858 * Replica 192.168.10.103:6379 asks for synchronization
    1468:M 10 Nov 2020 14:21:30.858 * Full resync requested by replica 192.168.10.103:6379
    1468: M 10 Nov 2020 14:21:30.858 * Starting BGSAVE for SYNC with target: disk
    1468:M 10 Nov 2020 14:21:30.859 * Background saving started by pid 1475
    1475:C 10 Nov 2020 14:21:30.861 * DB saved on disk
    1475:C 10 Nov 2020 14:21:30.861 * RDB: 4 MB of memory used by copy-on-write
    1468:M 10 Nov 2020 14:21:30.952 * Background saving terminated with success
    1468:M 10 Nov 2020 14:21:30.952 * Synchronization with replica 192.168.10.103:6379 succeeded
    
    • 不再赘述

5 )画图来看复制流程(全量复制)

  • 环境搭建好之后,slave节点就发起了一个 sync 的请求,这个请求是一个 全量复制
    • 其实增量无非就是在环境构建完成之后,每次你写入一个,我就复制一个写入一个复制一个
  • sync 的命令到主节点,主节点这边执行 BGSAVE 执行BGsave之后,生成RDB快照
  • 然后,主节点会把RDB的快照发送给 slave 节点
  • slave 节点拿到RDB快照之后,会把它节点上旧的数据全部删掉,加载RDB的文件
  • 在上述过程中,我们看下
    • master主节点,在执行 BGSAVE 的时候,它是一个非阻塞的
    • 就是说, 在生成RDB执行BGSAVE 期间, 仍然是可以对外提供服务的
    • 也就是说它仍然是可以读写的,如果说这时候有一些命令,它就会把命令写到缓冲区里边去
    • 就是我们的backlog里边,它为什么要这么做呢?
    • 一方面,为了提高性能,无阻塞可提供反馈
    • 另一方面,写到缓冲区里边,master 已经生成RDB快照发给 slave节点了
    • 后续的命令从节点就拿不到了,所以,给它放到这个缓冲区里边
    • 等 slave 这边RDB加载完之后,它再从缓冲区里边去拿走后续的那些命令
    • 相当于就是把整个的数据全部复制过去了
  • 所以,我们的 slave 除了加载 RDB 之外,它还会去缓冲区里边继续接受这些命令,最终完成一个init
  • 所以,这里面包含:RDB的加载完成和缓冲区命令的复制都完成了

6 )再来看下增量复制

  • 增量复制更多的是 Slave 初始化完成后,环境已经稳定了,这个时候,就会做增量的复制
  • 增量复制就是主服务器那边发生了写操作,它就会同步到从服务器的一个过程
  • 复制的过程就是
    • 主服务器执行一个命令,从服务器就会发送一个相同的写命令
    • 从服务器接收到之后就开始执行
  • 我们可以演示一下
    • 在从服务器中执行 $ sync 先建立连接
    • 在主服务器中,进行写操作 $ set age 18
    • 在从服务器终端中输入
      "PING"
      "SELECT","0"
      "set","age","18"
      "PING"
      
      • 可以看到,每10s就会PING一下,得到新的同步的命令这样保持心跳
  • 在2.8之前都是全量复制,之后便可以增量复制了

7 )主从复制的异步性

  • 主从复制这个过程,主节点是非阻塞的,在复制的这个流程中
  • 它是开启的一个后台子守护进程去做这件事情的,比如 BGSAVE 和 生成 RDB快照发送等
  • 当前服务器仍然是可以对外提供读写这样的一些请求的,这个就是非阻塞,体现异步性
  • 从节点也是一样的,比如说正在复制主节点的数据,这个SYNC的操作也是非阻塞的
  • 复制的过程中, 它可能就会有一点问题, 比如,正在复制时,一个查询过来
    • 那我可能查到的就是比如说一些老数据,这里边就会有脏读,数据不一致等等的问题
    • 这块在故障解决中有一些方案来处理

8 )过期 key 的处理

  • 实际上从节点是不会让 key 过期的,从节点它没有 key 过期的概念
  • 它会等待接收主节点delete的命令,可以看下面的演示
    • 从节点:$ sync 先监控下
    • 主节点:$ set age 18 ex 10
    • 查看从节点输出
      "PING"
      "set","age","18","ex","10"
      "PING"
      "DEL","age"
      "PING"
      
      • 可以看到,它在等主节点发DEL 命令
  • 也就是,当Master让key到期时,会合成一个 DEL 命令传输到所有 Slave

9 )加速复制

  • 上面看日志可知,每一次的复制都会生成RDB,然后把RDB的快照文件发给从节点
  • 如果说你的磁盘性能比较差,每一次的主从复制都要写入磁盘,如后再生成RDB文件发送给从节点,性能就会被降低,因为磁盘性能差
  • 可以不写入磁盘,直接生成RDB文件发给从节点就可以了,在 Redis@2.8.18这个版本之后,加入了这个功能,可以设置无需写入磁盘,直接把这个RDB的快照文件发给从节点
  • 修改配置:repl-diskless-sync yes 默认值是 no 不开启
    • 不开启的情况下,BGSAVE 先写磁盘,然后把生成RDB快照再发送
    • 设置为 yes 开启之后,就直接把RDB快照发给从节点
    • 不会写磁盘操作,这样就加速了复制

相关文章:

Redis: 主从复制原理

主从复制原理剖析 1 )配置 通过下面的从节点的配置项可以开启主从之间的复制功能slaveof 192.16.10.101 6379这里的复制包含全量复制和增量复制 2 )主节点的主从配置信息解析 查看主从之间的信息,在主节点上 $ info replication 打印出来的…...

PostgreSQL 向量扩展插件pgvector安装和使用

文章目录 PostgreSQL 向量扩展插件pgvector安装和使用安装postgresqlpgvector下载和安装安装错误调试错误调试1尝试解决 AP1 :启动postgresql 错误调试2尝试解决 AP2 : 使用apt-get install postgresql-server 错误调试3尝试解决 AP3 :卸载apt-get 安装 …...

【论文阅读】基于真实数据感知的模型功能窃取攻击

摘要 目的 模型功能窃取攻击是人工智能安全领域的核心问题之一,目的是利用有限的与目标模型有关的信息训练出性能接近的克隆模型,从而实现模型的功能窃取。针对此类问题,一类经典的工作是基于生成模型的方法,这类方法利用生成器…...

线程池:线程池的实现 | 日志

🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…...

海信和TCL雷鸟智能电视的体验

买了型号为32E2F(9008)的海信智能的电视有一段时间了,要使用这个智能电视还真能考验你的智商。海信电视有很多优点,它的屏幕比较靓丽,色彩好看,遥控器不用对着屏幕就能操作。但也有不少缺点。 1. 海信智能电视会强迫自动更新操作…...

自动化学习3:日志记录及测试报告的生成--自动化框架搭建

一.日志记录 1.配置文件pytest.ini:将日志写入文件方便日后查询或查看执行信息。 需要将文件处理器(文件存放位置/时间/格式等等)添加到配置文件中的【日志记录器】 # pytest.ini [pytest] # ---------------日志文件,需要配合…...

【STM32单片机_(HAL库)】4-1【定时器TIM】定时器中断点灯实验

1.硬件 STM32单片机最小系统LED灯模块 2.软件 timer驱动文件添加定时器HAL驱动层文件添加GPIO常用函数定时器中断配置流程main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "timer.h"int main(void) {H…...

Linux编译安装Mysql笔记

1.Mysql介绍 MySQL是一个广泛使用的开源关系型数据库管理系统(RDBMS),它基于SQL(Structured Query Language)进行操作。MySQL是由瑞典MySQL AB公司开发的,后来被Sun Microsystems收购,最终成为…...

在java后端发送HTTPClient请求

简介 HttpClient遵循http协议的客户端编程工具包支持最新的http协议 部分依赖自动传递依赖了HttpClient的jar包 明明项目中没有引入 HttpClient 的Maven坐标,但是却可以直接使用HttpClient原因是:阿里云的sdk依赖中传递依赖了HttpClient的jar包 发送get请…...

【STM32单片机_(HAL库)】4-3-2【定时器TIM】测量按键按下时间1——编程实现捕获功能

测量按键按下时长思路 测量按键按下时间实验目的 使用定时器 2 通道 2 来捕获按键 (按键接PA0)按下时间,并通过串口打印。 计一个数的时间:1us,PSC71,ARR65535 下降沿捕获、输入通道 2 映射在 TI2 上、不分…...

MySQL:2059 - Authentication plugin ‘caching_sha2_password‘ cannot be loaded

关于MySQL 客户端在尝试连接到 MySQL 服务器时报错:“2059 - Authentication plugin caching_sha2_password cannot be loaded”,具体是由于 MySQL 服务器默认使用的 caching_sha2_password 认证插件无法加载或不被当前客户端支持。 错误原因 MySQL 8.0…...

【JavaSE】反射、枚举、lambda表达式

目录 反射反射相关类获取类中属性相关方法常用获得类相关的方法示例常用获得类中属性相关的方法示例获得类中注解相关的方法 反射优缺点 枚举常用方法优缺点 枚举与反射lambda表达式语法函数式接口简化规则使用示例变量捕获集合中的应用优缺点 反射 Java的反射(refl…...

P3227 [HNOI2013] 切糕

题意: n ∗ m n*m n∗m的矩阵,每个点可以选择一个值 a i , j k a_{i,j}k ai,j​k,然后你能获得 w ( i , j , k ) w(i,j,k) w(i,j,k)的得分,但是相邻两点之间的差值有限制,让你求最大得分。 考虑最小割。 每个点 ( i , j ) (i,j) (i,j)弄出一条长为 R…...

超分服务的分量保存

分量说明 分量的概念主要是对于显卡解码,编码和网络传输而言,显卡可以同时进行几个线程,多个显卡可以分布式计算,对分量进行AI识别,比如我们有cuda的显卡,cuda的核心量可以分给不同的分片视频,第…...

Windows11系统下SkyWalking环境搭建教程

目录 前言SkyWalking简介SkyWalking下载Agent监控实现启动配置SkyWalking启动Java应用程序启动Elasticsearch安装总结 前言 本文为博主在项目环境搭建时记录的SkyWalking安装流程,希望对大家能够有所帮助,不足之处欢迎批评指正🤝&#x1f91…...

前端BOM常用操作

BOM操作常用命令详解及代码案例 BOM(Browser Object Model)是浏览器对象模型,是浏览器提供的JavaScript操作浏览器的API。BOM提供了与网页无关的浏览器的功能对象,虽然没有正式的标准,但现代浏览器已经几乎实现了Java…...

【Go】-viper库的使用

目录 viper简介 viper使用 通过viper.Set设置值 读取配置文件说明 读取配置文件 读取多个配置文件 读取配置项的值 读取命令行的值 io.Reader中读取值 写配置文件 WriteConfig() 和 SafeWriteConfig() 区别: viper简介 配置管理解析库,是由大神 Steve Fr…...

JavaWeb酒店管理系统(详细版)

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

C++ | 定长内存池 | 对象池

文章目录 C | 定长内存池 | 对象池一、内存池的引入二、代码中的内存池实现 - ObjectPool类(一)整体结构(二)内存分配 - New函数(三)内存回收 - Delete函数 三、内存池在TreeNode示例中的性能测试演示四、脱…...

python画图|自制渐变柱状图

在前述学习过程中,我们已经通过官网学习了如何绘制渐变的柱状图及其背景。 掌握一门技能的最佳检验方式就是通过实战,因此,本文尝试做一些渐变设计。 前述学习记录可查看链接: Python画图|渐变背景-CSDN博客 【1】柱状图渐变 …...

基于RPA+BERT的文档辅助“悦读”系统 | OPENAIGC开发者大赛高校组AI创作力奖

在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…...

K8S部署流程

一、war打包镜像(survey,analytics,trac系统) 代码打包成war准备tomcat的server.xml文件&#xff0c;修改connector中8080端口为项目的端口 修改前&#xff1a; <Connector port"8080" protocol"HTTP/1.1"connectionTimeout"20000"redirect…...

DevExpress WinForms中文教程:Data Grid - 如何添加或删除行?

本教程介绍DevExpress WinForm的Data Grid控件UI元素和API&#xff0c;它们使您和最终用户能够添加或删除数据行。您将首选学习如何启用内置的数据导航器&#xff0c;然后学习如何使用Microsoft Outlook启发的New Item行添加新记录。最后教程将向您展示基本的API&#xff0c;它…...

u盘格式化后数据能恢复吗?2024年Top4恢复神器来帮忙

在这个电脑和手机满天飞的时代&#xff0c;U盘是我们用来存东西和传文件的得力助手&#xff0c;特别重要。但是&#xff0c;有时候U盘可能会不小心被格式化了&#xff0c;里面的重要文件就不见了。那么&#xff0c;U盘格式化后的数据还能恢复吗&#xff1f;当然可以。今天会告诉…...

深度学习·Argparse

Argparse 命令行选项、参数和子命令解析器 ArgumentParser 命令行传参数->解析参数->获得对应参数 初始化&#xff1a;parser argparse.ArgumentParser(descriptionxxx)添加命令行参数&#xff1a; parser.add_argument("--training_filepath", typestr, he…...

制造企业为何需要PLM系统?PLM系统解决方案对制造业重要性分析

制造企业为何需要PLM系统&#xff1f;PLM系统解决方案对制造业重要性分析 新华社9月23日消息&#xff0c;据全国组织机构统一社会信用代码数据服务中心统计&#xff0c;我国制造业企业总量突破600万家。数据显示&#xff0c;2024年1至8月&#xff0c;我国制造业企业数量呈现稳…...

http协议中的header详细讲解

http协议中的header详细讲解 HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同&#xff0c;用于客户端和服务器之间的通信。 请求访问文本或图像等资源的一端称为客户端&#xff0c;而提供资源响应的一端称为服务器端。 HTTP 协议规定&#xff0c;请求从客户端发出&#xf…...

探索后量子安全:基于格加密技术的未来密码学展望

在信息技术日新月异的今天&#xff0c;量子计算作为下一代计算技术的代表&#xff0c;正逐步从理论走向实践。量子计算的出现对现有的加密体系构成了严重威胁&#xff0c;尤其是基于大数分解和离散对数难题的传统密码学&#xff08;如RSA和Diffie-Hellman协议&#xff09;。为了…...

WPF之UI进阶--完整了解wpf的控件和布局容器及应用

前面三篇有关WPF的基础介绍&#xff0c;分别介绍了wpf与winform的异同&#xff0c;wpf的事件生成和使用以及数据绑定。但我们还缺乏一副好的“皮囊”&#xff0c;所以从这篇开始我们来开始学习wpf的UI相关的内容&#xff0c;首当其冲的就是布局容器。 其实我们知道&#xff0c;…...

unity一键注释日志和反注释日志

开发背景&#xff1a;游戏中日志也是很大的开销&#xff0c;虽然有些日志不打印但是毕竟有字符串的开销&#xff0c;甚至有字符串拼接的开销&#xff0c;有些还有装箱和拆箱的开销&#xff0c;比如Debug.Log(1) 这种 因此需要注释掉&#xff0c;当然还需要提供反注释的功能&am…...

wordpress获取tags/百度推广客户端app下载

在很多的嵌入式的软件中&#xff0c;我们拿到代码&#xff0c;如果有文档先看看文档&#xff0c;没有文档也只能从Makefile的角度去看看软件的基本架构了。有一些大型的嵌入式软件项目的Makefile写的很复杂&#xff0c;这样在看学习Makefile的时候&#xff0c;需要一些技巧去分…...

自己做qq代刷网站要钱吗/自媒体怎么做

大家好,我是小马老师。 本文介绍python统计并输出CNA结构分析结果。 Ovito CNA模块可以分析不同时刻的晶体结构,但是在ovito软件中的分析结果不方便直接绘图输出,因此本文给出一个python脚本,运行之后可以直接绘制不同晶体结构的比例图。 程序使用方法: 复制以下pyth…...

返利网站建设/上海整站seo

我加载一个xml内容,并将其保存到磁盘.然后我读了它,并尝试解析.当我成功解析xml时,我应该忽略7行中的IOException吗&#xff1f;catch (IOException ignore) {}或者可能会出现一些问题&#xff1f;private HashMap loadContent(String url){try {BufferedInputStream bStream …...

网站建设发展情况/最近实时热点事件

回城传送–》《JAVA筑基100例》 文章目录 零、前言一、题目描述二、解题思路三、代码详解四、推荐专栏五、示例源码下载零、前言 ​ 今天是学习 JAVA语言 打卡的第47天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 ),读完文章之后,按解题思路,自己再实现一遍。在…...

可以做任务赚钱的网站有哪些/百度一下知道官网

QQ邮箱 设置-账户&#xff0c;生成授权码&#xff0c;确认POP3/SMTP服务是已开启的状态。 OutLook 文件 - 添加账户 - 手动设置或其他服务类型 - POP或IMAP 用户名填邮箱账户 其他设置勾选使用与接收邮件服务器相同的配置...

个人网站怎么做cps/昆明网络营销

1.创建UserPackage.java //-- 所在的包名&#xff0c;也就是位置。包在物理上就是一个文件夹&#xff0c;逻辑上代表一个分类的概念。 package Other; //-- 引入包Company中的Manager类 import Company.Manager;//-- 入口类&#xff08;主类&#xff09;&#xff0c;必须与文件…...