Redis-实践知识

转自极客时间Redis 亚风 原文视频:https://u.geekbang.org/lesson/535?article=681062

Redis最佳实践

普通KEY

Redis 的key虽然可以自定义,但是最好遵循下面几个实践的约定:
格式:[业务名称]:[数据名]:[id] 长度不超过44字节 不包含特殊字符
例如: login:user:10
这样做的好处是
• 可读性强
• 避免key冲突
• ⽅便管理
• 节省内存:key是string类型,底层编码包含int、embstr和raw三种。embstr在⼩于44字节使⽤,采⽤连续内存空间,内存占⽤更⼩。

set key "123"
object encoding key

在这里插入图片描述
在这里插入图片描述

BigKey

什么是bigKey?

  • BigKey通常以Key的⼤⼩和Key中成员的数量来综合判定,例如:
  • Key本身的数据量过⼤:⼀个String类型的Key,它的值为5 MB(key + val 加在一起 也就是一个Entry)。
  • Key中的成员数过多:⼀个ZSET类型的Key,它的成员数量为10,000个。
    Key中成员的数据量过⼤:⼀个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总⼤⼩为100 MB。
    推荐值:
    单个key的value⼩于10KB。
    对于集合类型的key,建议元素数量⼩于1000。
    BigKey的问题
    • ⽹络阻塞
    对Bigkey执⾏读请求时,少量的QPS就可能导致带宽使⽤率被占满,导致Redis实例,乃⾄所在物理机变慢
    • 数据倾斜
    BigKey所在的Redis实例内存使⽤率远超其他实例,⽆法使数据分⽚的內存资源达到均衡
    • Redis阻塞
    对元素较多的hash、 list、 zset等做运算会耗时较久,使主线程被阻塞
    • CPU压⼒
    对BigKey的数据序列化和反序列化会导致CPU的使⽤率飙升,影响Redis实例和本机其它应⽤

BigKey的发现
• redis-cli --bigkeys
利⽤ redis-cli提供的–bigkeys参数,可以遍历分析所有key,并返回Key的整体统计信息与每个数据的Top1的big key

redis-cli --bigkeys #扫描bigkeys

这里只得出了最大的key是54bytes,没有统计有那些key占用了多少空间,实际用用价值不大。
在这里插入图片描述

memory usage key #使用内存大小 (integer) 112
strlen key #也是使用内存大小
llen list #求内存大小
#最好是使用后面两个命令来求  memory usage性能不好

在这里插入图片描述

• scan扫描
⾃⼰编程,利⽤scan扫描Redis中的所有key,利⽤strlen、hlen等命令判断key的⻓度(此处不建议使⽤MEMORY USAGE)

scan 0 #第一页是0
#第二页则是 返回什么值 往下翻页就是转这个值
scan 7

在这里插入图片描述

// 自己编程
final static int STR_MAX_LEN = 10 * 1024;
final static int HASH_MAX_LEN = 1000;@Testvoid testScan() {int maxLen = 0;long len = 0;String cursor = "0";do {// 扫描并获取⼀部分keyScanResult<String> result = jedis.scan(cursor);// 记录cursorcursor = result.getCursor();List<String> list = result.getResult();if (list == null || list.isEmpty()) {break;}// 遍历for (String key : list) {// 判断key的类型String type = jedis.type(key);switch (type) {case "string":len = jedis.strlen(key);maxLen = STR_MAX_LEN;break;case "hash":len = jedis.hlen(key);maxLen = HASH_MAX_LEN;break;case "list":len = jedis.llen(key);maxLen = HASH_MAX_LEN;break;case "set":len = jedis.scard(key);maxLen = HASH_MAX_LEN;break;case "zset":len = jedis.zcard(key);maxLen = HASH_MAX_LEN;break;default:break;}if (len >= maxLen) {System.out.printf("Found big key : %s, ty
pe: %s, length or size: %d %n", key, type, len);}}} while (!cursor.equals("0"));}

• 第三⽅⼯具
利⽤第三⽅⼯具,如 Redis-Rdb-Tools 分析RDB快照⽂件,全⾯分析内存使⽤情况(推荐使用,但是实时性比较差)
• ⽹络监控
⾃定义⼯具,监控进出Redis的⽹络数据,超出预警值时主动告警。直接监控网络数据包。

如何删除BigKey
BigKey内存占⽤较多,即便时删除这样的key也需要耗费很⻓时间,导致
Redis主线程阻塞,引发⼀系列问题。
• redis 3.0 及以下版本
如果是集合类型,则遍历BigKey的元素,先逐个删除⼦元素,最后删除Bigkey
• Redis 4.0以后
Redis在4.0后提供了异步删除的命令:unlink

怎么存储key
例1:⽐如存储⼀个User对象,我们有三种存储⽅式:
⽅式⼀:json字符串

user:1 {"name":"jack","age":21}

优点:
简单粗暴
缺点:
数据耦合,不够灵活
方式二
字段打散

user:1:name jack
user:1:age 21

优点:可以灵活访问对象任意字段
缺点:占⽤空间⼤、没办法做统⼀控制
方式三

hset uid name zhonglimo #单字段赋值
hmset uid name zhonglimo age 24 #多字段赋值

在这里插入图片描述
优点:底层使⽤ziplist,空间占⽤⼩,可以灵活访问对象的任意字段
缺点:代码相对复杂
实战案例

假如有hash类型的key,其中有100万对field和value,field是⾃增id,这个key存在什么问题?如何优化?
在这里插入图片描述

存在的问题:
• hash的entry数量超过500时,会使⽤dict⽽不是ZipList,内存占⽤较多
• 可以通过hash-max-ziplist-entries配置entry上限。但是如果entry过多就会
导致BigKey问题
解决方案一直接将hash进行拆分成String:
在这里插入图片描述
存在的问题:
• string结构底层没有太多内存优化,内存占⽤较多
• 想要批量获取这些数据⽐较麻烦

方式二:拆分为⼩的hash,将 id / 100 作为key,将id % 100 作为field,这样每100个元素为⼀个Hash

在这里插入图片描述

HotKey

比如我有一个redis集群,由于2有一个热键,所有的请都打到了这个机器上有可能这个机器扛不住压力会挂掉,服务因而无法使用。
在这里插入图片描述
如果是读:
比如用哈希取模的方法进行路由到不同的机器,但是键也要做同样的拆分因为一个集群不能相同的键。

在这里插入图片描述
如果是写,比如秒杀扣库存,每台机器存放100个库存:
在这里插入图片描述
但是如果消耗到最后可能有碎片,比如剩了5个这个时候可以通过限流排队取消耗这些碎片。还有一种解决方案是消耗到剩一些碎片的时候,直接关闭流量,保证不超消费就行。

Pipeline批处理

MSET(不能被打断)虽然可以批处理,但是却只能操作部分数据类型,因此如果有对复杂数据类型的批处理需要,建议使⽤Pipeline功能:

void testPipeline() {Pipline pipeline = jedis.pipelined();for (int i = 1; i <= 10000; i ++) {if (i % 1000 == 0{pipline.sync();}}
}

注意事项:
• 批处理时不建议⼀次携带太多命令
• Pipeline的多个命令之间不具备原⼦性

MSET/Pipeline这样的批处理需要在⼀次请求中携带多条命令,⽽此时如果Redis是⼀个集群,那批处理命令的多个key必须落在⼀个插槽中,否则就会导致执⾏失败。
解决方案:
在这里插入图片描述
并行Slot在spring中的应用Spring->lettuce or Jedis->MultiKeyCommands

@Override
public RedisFuture<String> mset(Map<K,V> map) {Map<Integer, List<K>> partitioned = SlotHash.partition(codec, map.keySet());if (partitioned.size() < 2) {return super.mset(map);}
}

hash_tag

mset {a}name  zhangsan {a}age 12 {a}set male #这个hash Tag可以将key路由到同一个槽中

但是hash_tag 存在数据倾斜的问题,实战中推荐使用并行slot.

RDB 数据文件备份

RDB全称Redis Database Backup file (Redis数据备份⽂件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照⽂件,恢复数据。快照⽂件称为RDB⽂件,默认是保存在当前运⾏⽬录。

#有两种命令
save #由redis主进程来执行RDB,会阻塞所有命令
#fork 出⼀个⼦进程,⼦进程执⾏,不会阻塞 Redis 主线程,默认选项
bgsave #开启子进程执行RDB,避免主进程受到影响

Redis 可以通过创建快照来获得存储在内存⾥⾯的数据在 某个时间点 上的副本。Redis 创建快照之后,可以对快照进⾏备份,可以将快照复制到其他服务器从⽽创建具有相同数据的服务器副本(Redis 主从结构,主要⽤来提⾼Redis 性能),还可以将快照留在原地以便重启服务器的时候使⽤。快照持久化是 Redis 默认采⽤的持久化⽅式,在 redis.conf 配置⽂件中默认有此下配置:

#这些配置是一个或的关系,可以多个都生效,底层执行的都是bgsave 会自动转换为bgsave
save 900 1 #900秒以后如果有一个key变化触发bgsave
save 300 10 #300秒以后如果有10个key变化可以出发bgsave
save 60 10000 #一分钟如果有10000个key发生变化触发bgsave
rdbcompression yes #是否开启压缩,建议不开启,压缩会消耗cpu
dbfilename dump.rdb #rdb文件名称
dir ./ #文件保存目录

bgsave开始时会fork主进程得到⼦进程,⼦进程共享主进程的内存数据。完成fork后读取内存数据并写RDB ⽂件。fork采⽤的是copy-on-write技术:当主进程执⾏读操作时,访问共享内存;当主进程执⾏写操作时,则会拷⻉⼀份数据,执⾏写操作。
在这里插入图片描述

AOF 追加文件

AOF全称为Append Only File(追加⽂件)。Redis处理的每⼀个写命令都会记录在AOF⽂件,可以看做是命令⽇志⽂件。
与快照持久化相⽐,AOF 持久化的实时性更好。默认情况下 Redis 没有开启 AOF⽅式的持久(Redis6.0 之后已经默认是开启了),可以通过 appendonly 参数开启:appendonly yes

开启 AOF 持久化后每执⾏⼀条会更改 Redis 中的数据的命令,Redis 就会将该命令写⼊到 AOF 缓冲区(用户空间) server.aof_buf 中,然后再写⼊到 AOF ⽂件中(此时在内核缓存区),最后再根据持久化⽅式( fsync策略)的配置来决定何时将系统内核缓存区的数据同步到硬盘中的。

只有同步到磁盘中才算持久化保存了,否则依然存在数据丢失的⻛险,⽐如说:系统内核缓存区的数据还未同步,磁盘机器就宕机了,那这部分数据就算丢失了。

AOF ⽂件的保存位置和 RDB ⽂件的位置相同,都是通过 dir 参数设置的,默认的⽂件名appendonly.aof。

AOF 持久化功能的实现分为 5 步:
1 命令追加(append) :所有的写命令会追加到 AOF 缓冲区中。
2 ⽂件写⼊(write) :将 AOF 缓冲区的数据写⼊到 AOF ⽂件中。这⼀步
需要调⽤write函数(系统调⽤),write将数据写⼊到了系统内核缓冲区之
后直接返回了(延迟写)。注意!此时并没有同步到磁盘。
3 ⽂件同步(fsync) :AOF 缓冲区根据对应的持久化⽅式( fsync 策略)
向硬盘做同步操作。这⼀步需要调⽤ fsync 函数(系统调⽤), fsync 针
对单个⽂件操作,对其进⾏强制硬盘同步,fsync 将阻塞直到写⼊磁盘完
成后返回,保证了数据持久化。
4 ⽂件重写(rewrite) :随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件
进⾏重写,达到压缩的⽬的。
5 重启加载(load) :Redis 重启时,可以加载 AOF ⽂件进⾏数据恢复。

Linux 系统直接提供了⼀些函数⽤于对⽂件和设备进⾏访问和控制,这些函数被称为系统调⽤(syscall)。

write :写⼊系统内核缓冲区之后直接返回(仅仅是写到缓冲区),不会⽴即同步到硬盘。虽然提⾼了效率,但也带来了数据丢失的⻛险。同步硬盘操作通常依赖于系统调度机制,Linux 内核通常为 30s 同步⼀次,具体值取决于写出的数据量和 I/O 缓冲区的状态。
fsync : fsync⽤于强制刷新系统内核缓冲区(同步到到磁盘),确保写磁盘操作结束才会返回。

在这里插入图片描述
Redis fsync策略
在 Redis 的配置⽂件中存在三种不同的 AOF 持久化⽅式( fsync策略),它们分别是:
• appendfsync always:主线程调⽤ write 执⾏写操作后,后台线程( aof_fsync 线程)⽴即会调⽤ fsync 函数同步 AOF ⽂件(刷盘),fsync 完成后线程返回,这样会严重降低 Redis 的性能

• appendfsync everysec :主线程调⽤ write 执⾏写操作后⽴即返回,由后台线程( aof_fsync 线程)每秒钟调⽤ fsync 函数(系统调⽤)同步⼀次 AOF ⽂件

• appendfsync no :主线程调⽤ write 执⾏写操作后⽴即返回,让操作系统决定何时进⾏同步,Linux 下⼀般为 30 秒⼀次为了兼顾数据和写⼊性能,可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步⼀次 AOF ⽂件,Redis 性能收到的影响较⼩。⽽且这样即使出现系统崩溃,⽤户最多只会丢失⼀秒之内产⽣的数据。当硬盘忙于执⾏写⼊操作的时候,Redis 还会优雅的放慢⾃⼰的速度以便适应硬盘的最⼤写⼊度。
**Multi Part AOF **
从 Redis 7 开始,Redis 使⽤了 Multi Part AOF 机制。顾名思义,Multi Part AOF 就是将原来的单个 AOF ⽂件拆分成多个 AOF ⽂件。在 Multi Part AOF 中,AOF ⽂件被分为三种类型,分别为:
BASE:表示基础 AOF ⽂件,它⼀般由⼦进程通过重写产⽣,该⽂件最多只有⼀个。
INCR:表示增量 AOF ⽂件,它⼀般会在 AOFRW 开始执⾏时被创建,该⽂件可能存在多个。
HISTORY:表示历史 AOF ⽂件,它由 BASE 和 INCR AOF 变化⽽来,每次 AOFRW 成功完成时,本次 AOFRW 之前对应的 BASE 和 INCR AOF 都将变为 HISTORY,HISTORY 类型的 AOF 会被 Redis ⾃动删除。
当 AOF 变得太⼤时,Redis 能够在后台⾃动重写 AOF 产⽣⼀个新的 AOF ⽂件,这个新的 AOF ⽂件和原有的 AOF ⽂件所保存的数据库状态⼀样,但体积更⼩。

AOF重写

AOF 重写是⼀个有歧义的名字,该功能是通过读取数据库中的键值对来实现的(扫描键值对重新写一个新文件,不会对之前的AOF进行读写),程序⽆须对现有 AOF ⽂件进⾏任何读⼊或写⼊操作。

由于 AOF 重写会进⾏⼤量的写⼊操作,为了避免对 Redis 正常处理命令请求造成影响,Redis 将 AOF 重写程序放到⼦进程⾥执⾏。
AOF ⽂件重写期间,Redis 还会维护⼀个 AOF 重写缓冲区,该缓冲区会在⼦进程创建新 AOF ⽂件期间,记录服务器执⾏的所有写命令。当⼦进程完成创建新 AOF ⽂件的⼯作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF ⽂件的末尾,使得新的 AOF ⽂件保存的数据库状态与现有的数据库状态⼀致。最后,服务器⽤新的 AOF ⽂件替换旧的 AOF ⽂件,以此来完成 AOF ⽂件重写操作。

开启 AOF 重写功能,可以调⽤ BGREWRITEAOF 命令⼿动执⾏,也可以设置下⾯两个配置项,让程序⾃动决定触发时机:

#增长超过多少百分比触发重写
auto-aof-rewrite-percentage 100
#体积多大触发重写
auto-aof-rewrite-min-size 64mb

Redis 7.0 版本之前,如果在重写期间有写⼊命令,AOF 可能会使⽤⼤量内存,重写期间到达的所有写⼊命令都会写⼊磁盘两次。AOF 重写期间的增量数据如何处理⼀直是个问题,在过去写期间的增量数据需
要在内存中保留,写结束后再把这部分增量数据写⼊新的 AOF ⽂件中以保证数据完整性。可以看出来 AOF 写会额外消耗内存和磁盘 IO,这也是 Redis AOF 写的痛点,虽然之前也进⾏过多次改进但是资源消耗的本质问题⼀直没有解决。
阿⾥ Redis 在最初也遇到了这个问题,在内部经过多次迭代开发,实现了 Multi-part AOF 机制来解决,同时也贡献给了社区并随此次 7.0 发布。具体⽅法是采⽤ base(全量数据)+incr(增量数据)独⽴⽂件存储的⽅式。由于 RDB 和 AOF 各有优势,Redis 4.0 开始⽀持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF ⽂件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF ⾥⾯的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

RDB与AOF的对比

RDB ⽐ AOF 优秀的地⽅ :
RDB ⽂件存储的内容是经过压缩的⼆进制数据, 保存着某个时间点的数据集,⽂件很⼩,适合做数据的备份,灾难恢复。AOF ⽂件存储的是每⼀次写命令,类似于 MySQL 的 binlog ⽇志,通常会必 RDB ⽂件⼤很多。当 AOF 变得太⼤时,Redis 能够在后台⾃动重写 AOF。新的 AOF ⽂件和原有的 AOF ⽂件所保存的数据库状态⼀样,但体积更⼩。不过, Redis 7 之前,如果在重写期间有写⼊命令,AOF 可能会使⽤⼤量内存,重写期间到达的所有写⼊命令都会写⼊磁盘两次。使⽤ RDB ⽂件恢复数据,直接解析还原数据即可,不需要⼀条⼀条地执⾏命令,速度⾮常快。⽽ AOF 则需要依次执⾏每个写命令,速度⾮常慢。也就是
说,与 AOF 相⽐,恢复⼤数据集的时候,RDB 速度更快。

AOF ⽐ RDB 优秀的地⽅ :
RDB 的数据安全性不如 AOF,没有办法实时或者秒级持久化数据。⽣成 RDB ⽂件的过程是⽐较繁重的, 虽然 BGSAVE ⼦进程写⼊ RDB ⽂件的⼯作不会阻塞主线程,但会对机器的 CPU 资源和内存资源产⽣影响,严重的情况下甚⾄会直接把 Redis 服务⼲宕机。AOF ⽀持秒级数据丢失(取决 fsync 策略,如果是 everysec,最多丢失 1 秒的数据),仅仅是追加命令到 AOF ⽂件,操作轻量。
RDB ⽂件是以特定的⼆进制格式保存的,并且在 Redis 版本演进中有多个版本的 RDB,所以存在⽼版本的 Redis 服务不兼容新版本的 RDB 格式的问题。AOF 以⼀种易于理解和解析的格式包含所有操作的⽇志。你可以轻松地导出 AOF ⽂件进⾏分析。⽐如,如果执⾏FLUSHALL命令意外地刷新了所有内容后,删除最新命令并重启即可恢复之前的状态。持久化可以保证数据安全,但会带来额外的开销,请遵循下列建议:
• ⽤来做缓存的Redis实例尽量不要开启持久化功能
• 建议关闭RDB持久化功能,使⽤AOF持久化
• 利⽤脚本定期在slave节点做RDB,实现数据备份
• 设置合理的rewrite阈值,避免频繁的bgrewrite
• 配置no-appendfsync-on-rewrite =yes,禁⽌在rewrite期间做aof,避免因
AOF引起的阻塞

部署建议

• Redis实例的物理机要预留⾜够内存,应对fork和rewrite
• 单个Redis实例内存上限不要太⼤,例如8G。可以加快fork的速度(fork是到页如果句柄太大,fork也会很慢)、减少主从同步、数据迁移压⼒
• 不要与CPU密集型应⽤部署在⼀起
• 不要与⾼硬盘负载应⽤⼀起部署。例如:数据库、消息队列

慢查询

慢查询阈值可以通过配置指定:slowlog-log-slower-than:慢查询阈值,单位是微秒。默认是10000(10ms),建议1000(1ms)
慢查询会被放⼊慢查询⽇志中,⽇志的⻓度有上限,可以通过配置指定:slowlog-max-len:慢查询⽇志(本质是⼀个队列)的⻓度。默认是128,建议1000
• slowlog len:查询慢查询⽇志⻓度
• slowlog get n:读取n条慢查询⽇志
• slowlog reset:清空慢查询列表、

Redis 安全设置

Redis会绑定在0.0.0.0:6379,这样将会将Redis服务暴露到公⽹上,⽽Redis如果没有做身份认证,会出现严重的安全漏洞.
漏洞出现的核⼼的原因有以下3点:
• Redis未设置密码
• 利⽤了Redis的config set命令动态修改Redis配置
• 使⽤了Root账号权限启动Redis

为了避免漏洞,这⾥给出⼀些建议:
• Redis⼀定要设置密码
• 禁⽌线上使⽤下⾯命令:keys、 flushall、 flushdb、 config set等命令。可以利⽤rename-command禁⽤。

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 #把修改配置的命令重新命名
rename-command KEYS ""      #必禁命令,线上用这种查询方式绝对是不对的
rename-command FLUSHALL ""  #必禁命令,谁会清除数据呢
rename-command FLUSHDB ""   #必禁命令,谁会清除数据呢
rename-command CONFIG ""    #可以考虑重命名下

• bind:限制⽹卡,禁⽌外⽹⽹卡访问
• 开启防⽕墙
• 不要使⽤Root账户启动Redis
• 尽量不是有默认的端⼝

Redis内存优化

当Redis内存不⾜时,可能导致Key频繁被删除、响应时间变⻓、QPS不稳定等问题。当内存使⽤率达到90%以上时就需要我们警惕,并快速定位到内存占⽤的原因。
在这里插入图片描述
redis info 详解

内存占用
在这里插入图片描述
内存缓冲区常⻅的有三种:
复制缓冲区:主从复制的repl-backlog_buf,如果太⼩可能导致频繁的全量复制,影响性能。通过repl-backlog-size来设置,默认1mb。
AOF缓冲区:AOF刷盘之前的缓存区域,AOF执⾏rewrite的缓冲区。⽆法设置容量上限。
客户端缓冲区:分为输⼊缓冲区和输出缓冲区,输⼊缓冲区最⼤1G且不能设置,输出缓冲区可以设置。
通过下面这个命令进行设置:
class 是一个什么,集群的时候配replica

在这里插入图片描述

CLIENT LIST #可以通过Client List 定位问题客户端
Redis集群优化

在Redis的默认配置中,如果发现任意⼀个插槽不可⽤,则整个集群都会停⽌对外服务:

cluster-require-full-coverage  yes #通过这个配置来进行设置 no 是有个一个插槽不可以也可以使用

集群节点之间会不断的互相Ping来确定集群中其它节点的状态。每次Ping携带的信息⾄少包括:
• 插槽信息
• 集群状态信息
• 集群中节点越多,集群状态信息数据量也越⼤,10个节点的相关信息可能达到1kb,此时每次集群互通需要的带宽会⾮常⾼。
解决途径:
• 避免⼤集群,集群节点数不要太多,最好少于1000,如果业务庞⼤,则建⽴多个集群
• 避免在单个物理机中运⾏太多Redis实例
• 配置合适的cluster-node-timeout值

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Jmeter】Jmeter基础9-BeanShell介绍

3、BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法。 3.1、Jmeter中使用的BeanShell 在Jmeter中&#xff0c;除了配置元件&#xff0c;其他类型的元件中都有BeanShell。BeanShell 是一种完全符合Java语法规范的脚本语言,并且又拥…

TCP并发服务器

一.进程实现TCP并发服务器 #include <func.h> #define PORT 6666 #define IP "192.168.124.42"void handler(int arm) {while(waitpid(-1,NULL,WNOHANG) > 0); } int main(int argc, const char *argv[]) {//接受17号信号signal(17, handler);i…

Matlab之State Flow

打开方式 方式一&#xff1a;在命令窗口输入State Flow或者简写sf就能打开&#xff0c;并且会自动打开State Flow 的Library。从左到右分别是图表、真值表、状态转换表、例子、顺序查看&#xff0c;可以加入到Simulink当中。 方式二&#xff1a;从Simulink Library里面添加Sta…

EB tresos 配置I2c - 实现与PF8200的读写操作

文章目录 前言一、EB工具链配置1、I2c模块1&#xff09;新建模块2&#xff09;配置General3&#xff09;配置I2cChannel 2、Port模块1&#xff09;配置SDA2&#xff09;配置SCL 二、代码分析1、申明一个I2c配置结构体数组&#xff0c;用于I2c所有读操作。2、搭建读操作函数 三、…

得物大模型平台,业务效果提升实践

一、背景 得物大模型训练与推理平台上线几个月后&#xff0c;我们与公司内部超过 10 个业务领域展开了全面的合作。在一些关键业务指标方面&#xff0c;取得了显著的成效&#xff0c;例如&#xff1a; 效率相关部门的合作&#xff0c;多维度打标总正确率取得 2 倍以上提升。利…

Spring中的上下文工具你写的可能有bug

文章目录 前言功能第一种&#xff1a;ApplicationContext第二种方式&#xff1a;ApplicationContextAware第三种&#xff1a;BeanFactoryPostProcessor 源码第一种第二种第三种 前言 本篇是针对如何写一个比较好的spring工具的一个探讨。 功能 下面三种方式&#xff0c;你觉…

智能三维数据虚拟现实电子沙盘

一、概述 易图讯科技&#xff08;www.3dgis.top&#xff09;以大数据、云计算、虚拟现实、物联网、AI等先进技术为支撑&#xff0c;支持高清卫星影像、DEM高程数据、矢量数据、无人机倾斜摄像、BIM模型、点云、城市白模、等高线、标高点等数据融合和切换&#xff0c;智能三维数…

CTF特训(一):ctfshow-RCE挑战

CTF特训(一)&#xff1a;ctfshow-RCE挑战 FLAG&#xff1a;可后来&#xff0c;除了梦以外的地方&#xff0c;我再也没有见过你 专研方向: 代码审计&#xff0c;PHP 每日emo&#xff1a;其实挺迷茫的&#xff0c;不知道该干什么,(骗你的) RCE挑战1 <?phperror_reporting(0)…

Qt Creator可视化交互界面exe快速入门3

上一期介绍的通过Qt Creator的组件直接拖拽的方式完成了一个界面&#xff0c;这期介绍按钮的信号交互。 专有名称叫信号与槽 实现方法1&#xff1a; 鼠标右键选择转化为槽就会跳出这样的界面 选择第一个为单击信号。然后就会跳转到代码界面。多了on_pushButton_clicked()。 …

2024深入评测CleanMyMac X4.14.6破解版新的功能

随着时间的推移&#xff0c;我们的Mac电脑往往会变得越来越慢&#xff0c;存储空间变得越来越紧张&#xff0c;这时候一个优秀的清理工具就显得尤为重要。作为一款备受好评的Mac清理工具&#xff0c;它能够为你的Mac带来全方位的清理和优化。在本文中&#xff0c;我们将深入评测…

ADRC-跟踪微分器TD的Maltab实现及参数整定

目录 问题描述&#xff1a; 跟踪微分器TD基本概念&#xff1a; Matlab及其实现&#xff1a; 跟踪效果&#xff1a; 例1&#xff1a;跟踪信号 sin(t) 0.5*rand(1,1)。 例2&#xff1a;跟踪部分时段为方波的信号&#xff0c;具体形式见代码get_command。 参数整定&#xf…

HarmonyOS - 基础组件绘制

文章目录 所有组件开发 tipsBlankTextImageTextInputButtonLoadingProgress 本文改编自&#xff1a;<HarmonyOS第一课>从简单的页面开始 https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667360160710997 所有组件 在 macOS 上&#xff0c;组…

【WSL2】安装和配置ubuntu

文章目录 1. 安装WSL22. 安装ubuntu2.1. 通过Microsoft Store2.1. 通过命令行 3. ubuntu的使用3.1. 创建管理员root账户3.2. 换源3.3. 安装图形化界面 1. 安装WSL2 在控制面板 - 程序 - 程序与功能中点击启用或关闭Windows功能&#xff0c;选择 虚拟机平台适用于Linux的Window…

Android Studio 如何隐藏默认标题栏

目录 前言 一、修改清单文件 二、修改代码 三、更多资源 前言 在 Android 应用中&#xff0c;通常会有一个默认的标题栏&#xff0c;用于显示应用的名称和一些操作按钮。但是&#xff0c;在某些情况下&#xff0c;我们可能需要隐藏默认的标题栏&#xff0c;例如自定义标题栏…

File Inclusion(Pikachu)

File Inclusion(local) 这里随便点击一个提交 观察url&#xff0c;显示是一个文件file1.php 可以直接通过url修改这个文件 找到自己的文件&#xff08;本地文件&#xff09;shell.php的路径写上去 就可以看到 File Inclusion&#xff08;remote&#xff09; 提交的是一个目标…

桶装水送水小程序:提升服务质量的利器

随着移动互联网的发展&#xff0c;越来越多的消费者通过手机在线购物和订购商品。如果你是一名桶装水供应商&#xff0c;想要拓展线上业务&#xff0c;那么开发一个桶装水微信小程序将是一个明智的选择。本文将指导你从零开始开发一个桶装水微信小程序&#xff0c;让你轻松完成…

Oracle初始化参数修改后,是否需要重启才能生效

可以查看 v$parameter或v$parameter2动态性能视图的ISSYS_MODIFIABLE列。此列指示是否可以使用 ALTER SYSTEM 更改参数以及更改何时生效&#xff1a; IMMEDIATE - 无论用于启动实例的参数文件的类型如何&#xff0c;都可以使用 ALTER SYSTEM 更改参数。 更改立即生效。DEFERRE…

如何底层调用最快地复制OPC数据到关系数据库

计算机上的二大应用&#xff0c;一是从WEB服务器上获得数据&#xff0c;另一种是向关系数据库中写入数据。在上集我已提出了一个从WEB上获得OPC数据的独创方法&#xff0c;现在谈谈第二种如何快速地把OPC数据写进到数据库中&#xff0c;这也是Calssic OPC最典型的一个应用场景。…

2023.12.25 关于 Redis 数据类型 Hash 常用命令、内部编码、应用场景

目录 Hash 数据类型 Hash 操作命令 HSET HGET HEXISTS HDEL HKEYS HVALS HGETALL HMGET HLEN HSETNX HINCRBY HINCRBYFLOAT HSTRLEN Hash 编码方式 理解什么是压缩 Hash 实际应用 Cache 缓存 Hash 数据类型 整体上来说 Redis 是键值对结构&#xff0c;其中 …

【深度学习目标检测】十一、基于深度学习的电网绝缘子缺陷识别(python,目标检测,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…