TDengine 性能监控与调优实战指南(二)
四、TDengine 性能调优实战
4.1 硬件层面优化
硬件是 TDengine 运行的基础,其性能直接影响着 TDengine 的整体表现。在硬件层面进行优化,就如同为高楼大厦打下坚实的地基,能够为 TDengine 的高效运行提供有力支持。
- CPU:CPU 作为计算机的核心组件,其性能对 TDengine 的影响至关重要。在数据处理过程中,CPU 负责执行各种计算任务,如数据的插入、查询、聚合等。选择高性能的 CPU,如具有多核、高主频的处理器,能够显著提升 TDengine 的处理能力。在大数据量的物联网场景中,大量的传感器数据需要实时处理和分析,多核 CPU 可以并行处理这些任务,大大提高处理效率。合理配置 CPU 核数也非常关键,根据 TDengine 的运行需求和业务负载,将 CPU 核数配置为与业务需求相匹配的数值,能够充分发挥 CPU 的性能优势。如果业务负载较轻,过多的 CPU 核数会造成资源浪费;而如果业务负载较重,CPU 核数不足则会导致性能瓶颈。
- 内存:内存是数据处理和存储的临时空间,充足的内存能够确保 TDengine 快速读写数据。在处理大规模数据时,如果内存不足,TDengine 就需要频繁地进行磁盘 I/O 操作来交换数据,这会极大地降低系统性能。为 TDengine 分配足够的内存是提高性能的重要措施之一。在配置内存时,需要根据业务数据量和并发访问情况来确定合适的内存大小。在金融交易数据处理场景中,由于交易数据量巨大且需要实时处理,就需要为 TDengine 分配较大的内存,以保证数据的快速读写和查询的高效执行。还可以通过调整内存分配策略,如增加缓存区大小,来提高内存的使用效率。
- 磁盘:磁盘的性能对 TDengine 的数据存储和读取有着直接的影响。选择高速磁盘,如 SSD(固态硬盘),能够大幅提高数据的读写速度。SSD 具有读写速度快、响应时间短等优点,相比传统的机械硬盘,能够显著提升 TDengine 的性能。在数据密集型的应用场景中,如日志存储和分析,大量的数据需要频繁地写入和读取磁盘,使用 SSD 可以大大提高数据处理的效率。优化磁盘 I/O 设置也非常重要,如调整磁盘队列深度、优化磁盘调度算法等,能够进一步提升磁盘的性能。合理规划磁盘空间,避免磁盘空间不足对 TDengine 性能产生影响。
4.2 配置参数调优
TDengine 的配置参数众多,这些参数就像精细的调节旋钮,对其性能有着至关重要的影响。合理调整配置参数,能够让 TDengine 更好地适应不同的业务场景,发挥出最佳性能。
4.2.1 核心配置参数解读
- buffer:buffer 是 TDengine 用于缓存数据的内存空间大小,它就像一个临时的数据仓库。较大的 buffer 可以容纳更多的数据,减少数据写入磁盘的次数,从而提高写入性能。在物联网数据采集场景中,大量的传感器数据会在短时间内涌入,如果 buffer 过小,数据就需要频繁地写入磁盘,导致写入速度变慢。但是,过大的 buffer 也会占用过多的内存资源,影响系统的整体性能,需要根据实际情况进行权衡。
- cache:cache 用于设置内存缓存的大小,它是提高查询性能的关键参数。TDengine 会将经常访问的数据缓存到内存中,当再次查询这些数据时,可以直接从缓存中获取,而不需要从磁盘读取,从而大大提高查询速度。在金融交易数据查询场景中,频繁查询的交易数据如果能够被缓存到内存中,就可以快速响应查询请求,提高业务处理效率。需要注意的是,cache 的大小也需要根据系统内存和业务需求进行合理设置。
- blocks:blocks 配置虚拟节点可以拥有的内存块数量,与 cache 一起决定了虚拟节点占用的内存大小。每个内存块都有一定的大小,通过调整 blocks 的数量,可以优化内存的使用效率。例如,在高并发的业务场景中,适当增加 blocks 的数量,可以提高数据的处理能力,但同时也会增加内存的占用。
- numOfCommitThreads:numOfCommitThreads 表示每个节点上的落盘线程数量,它决定了数据从内存持久化到磁盘的速度。在数据写入频繁的场景中,增加落盘线程数量可以加快数据落盘的速度,减少内存中的数据积压,从而提高系统的稳定性和写入性能。如果落盘线程数量过少,在高并发写入时,就可能导致内存中的数据无法及时落盘,影响系统的正常运行。
4.2.2 根据业务场景调整参数
不同的业务场景对 TDengine 的性能需求各不相同,因此需要根据具体的业务场景来调整配置参数,以实现性能的最优。
- 物联网数据采集场景:在物联网数据采集场景中,数据具有高并发、高频次写入的特点。针对这种场景,应适当增大 buffer 和 cache 的大小,以容纳更多的缓存数据,减少磁盘 I/O 操作。可以将 buffer 设置为较大的值,如 64MB 或 128MB,cache 也相应增大。增加 numOfCommitThreads 的数量,以加快数据落盘速度,确保数据的及时持久化。根据设备数量和数据量,合理调整其他参数,如 maxVgroupsPerDb 等,以优化数据的分布和存储。
- 金融交易数据处理场景:金融交易数据处理场景对数据的准确性和实时性要求极高,同时存在大量的复杂查询操作。在这种场景下,需要确保 cache 足够大,以缓存频繁查询的交易数据,提高查询响应速度。可以将 cache 设置为物理内存的较大比例,如 50% 或更高。优化查询相关的参数,如调整查询缓存策略、合理设置索引等,以提高查询性能。由于金融数据的重要性,还需要关注数据的安全性和一致性,相应地调整数据备份和恢复相关的参数。
- 工业监控场景:工业监控场景的数据量较大,且数据的存储和查询具有一定的周期性。对于这种场景,可以根据数据的存储周期和查询频率,合理设置数据保留时间和缓存策略。例如,对于短期需要频繁查询的数据,可以增加 cache 的大小;对于长期存储但不经常查询的数据,可以适当减小缓存,以节省内存资源。优化数据分区策略,按时间或设备进行分区,提高数据的存储和查询效率。根据工业监控系统的实时性要求,调整数据写入和查询的优先级,确保关键数据的及时处理。
4.3 数据库设计优化
数据库设计是 TDengine 性能优化的关键环节,合理的数据库设计能够提高数据的存储和查询效率,就像精心规划的城市布局能够使交通更加顺畅一样。
4.3.1 表结构设计原则
- 合理选择数据类型:在 TDengine 中,选择合适的数据类型对于节省存储空间和提高查询性能至关重要。对于整数类型的数据,应根据数据的范围选择合适的整数类型,如 TINYINT、SMALLINT、INT 或 BIGINT。如果数据范围较小,使用 TINYINT 或 SMALLINT 可以节省存储空间;对于浮点数类型的数据,应根据精度要求选择 FLOAT 或 DOUBLE。如果对精度要求不高,使用 FLOAT 可以减少存储空间的占用。对于字符串类型的数据,应根据实际长度选择合适的字符串类型,如 VARCHAR 或 NCHAR,并尽量避免使用过长的字符串。
- 设计超级表与子表关系:TDengine 的超级表和子表结构是其独特的数据模型,充分利用这种结构可以提高数据的管理和查询效率。超级表用于定义一组具有相同结构和属性的子表的模板,子表则是超级表的实例。在设计超级表和子表关系时,应根据业务需求合理划分超级表和子表。在物联网设备监控场景中,可以将所有设备的数据定义为一个超级表,每个设备的数据作为一个子表。通过这种方式,可以方便地对设备数据进行统一管理和查询,同时利用超级表的标签功能,可以快速过滤和查询特定设备的数据。
4.3.2 数据分区策略
- 按时间分区:按时间分区是 TDengine 中常用的数据分区策略之一,它将数据按照时间范围划分为不同的分区。在时间序列数据处理中,数据通常具有较强的时间相关性,按时间分区可以将不同时间段的数据存储在不同的分区中,提高查询效率。例如,在电力数据监控中,可以按天或按小时对数据进行分区。当查询某一天或某一时间段的数据时,只需要在相应的分区中进行查询,而不需要扫描整个数据集,从而大大提高查询速度。
- 按设备 ID 分区:在一些场景中,按设备 ID 分区也是一种有效的策略。它将不同设备的数据存储在不同的分区中,便于对设备数据进行管理和查询。在智能家居系统中,每个设备都有唯一的设备 ID,按设备 ID 分区可以将不同设备的数据分开存储,当需要查询某个设备的数据时,可以直接定位到对应的分区,提高查询效率。还可以根据设备的类型、地理位置等属性进行分区,进一步优化数据的管理和查询。
4.4 写入性能优化
写入性能是 TDengine 性能的重要指标之一,优化写入性能可以确保大量数据能够快速、准确地存储到数据库中。
4.4.1 批量写入
批量写入是提高写入性能的有效方法之一,它通过减少写入操作的次数,降低系统开销。在 TDengine 中,可以将多条数据组合成一个批量写入请求,一次性发送到服务器。例如,在物联网数据采集场景中,每个传感器可能会产生大量的数据,如果每次只写入一条数据,会产生大量的网络请求和系统开销。而将多条数据批量写入,可以大大减少网络请求的次数,提高写入效率。下面是一个使用 Python 语言进行批量写入的代码示例:
import taos
# 建立数据库连接
conn = taos.connect(host="localhost", user="root", password="taosdata", database="test")
cursor = conn.cursor()
# 准备批量写入的数据
data = [
(1619875200000, 10.5, 220, 0.8, "device1"),
(1619875201000, 10.6, 221, 0.81, "device1"),
(1619875202000, 10.7, 222, 0.82, "device2"),
# 更多数据...
]
# 执行批量写入
sql = "INSERT INTO meters (ts, current, voltage, phase, device_id) VALUES (%s, %s, %s, %s, %s)"
cursor.executemany(sql, data)
# 提交事务
conn.commit()
# 关闭连接
cursor.close()
conn.close()
在上述代码中,使用executemany方法将多条数据一次性插入到数据库中,大大提高了写入效率。
4.4.2 多线程写入
多线程写入是利用系统的多核资源,同时进行多个写入操作,从而提高写入性能。在高并发写入场景中,多线程写入可以充分发挥系统的潜力,加快数据的写入速度。例如,在大规模的物联网设备数据采集场景中,多个设备同时上传数据,使用多线程写入可以同时处理这些数据,避免写入操作的阻塞。下面是一个使用 Python 多线程进行写入的代码示例:
import taos
import threading
# 数据库连接信息
host = "localhost"
user = "root"
password = "taosdata"
database = "test"
# 写入数据的函数
def write_data(device_id):
conn = taos.connect(host=host, user=user, password=password, database=database)
cursor = conn.cursor()
for i in range(100):
ts = 1619875200000 + i * 1000
current = 10.0 + i * 0.1
voltage = 220 + i
phase = 0.8 + i * 0.01
sql = "INSERT INTO meters (ts, current, voltage, phase, device_id) VALUES (%s, %s, %s, %s, %s)"
cursor.execute(sql, (ts, current, voltage, phase, device_id))
conn.commit()
cursor.close()
conn.close()
# 创建多个线程进行写入
threads = []
device_ids = ["device1", "device2", "device3", "device4"]
for device_id in device_ids:
t = threading.Thread(target=write_data, args=(device_id,))
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join()
在上述代码中,创建了多个线程,每个线程负责写入一个设备的数据,通过多线程并发执行,提高了整体的写入性能。在使用多线程写入时,需要注意线程安全问题,避免多个线程同时访问和修改共享资源导致的数据不一致。
4.5 查询性能优化
查询性能直接影响用户对 TDengine 的使用体验,优化查询性能可以使数据的检索更加快速、高效。
4.5.1 查询语句优化
- 避免全表扫描:全表扫描是查询性能的一大瓶颈,它会扫描整个数据表,消耗大量的时间和资源。为了避免全表扫描,应尽量在查询条件中使用索引字段。在 TDengine 中,时间主列是默认的索引列,因此在查询时,尽量使用时间范围作为查询条件。例如,查询某一天的数据时,可以使用WHERE ts >= '2023-01-01 00:00:00' AND ts < '2023-01-02 00:00:00'这样的条件,利用时间索引快速定位到所需的数据。如果查询条件中涉及其他字段,可以考虑为这些字段创建索引,提高查询效率。
- 合理使用索引:索引就像书籍的目录,能够快速定位到所需的数据。在 TDengine 中,除了时间主列的默认索引外,可以根据查询需求为其他字段创建索引。在查询条件中经常使用的标签列,可以为其创建标签索引。例如,在设备监控场景中,如果经常根据设备 ID 查询数据,可以为设备 ID 列创建索引。创建索引时需要注意,索引虽然可以提高查询性能,但也会占用一定的存储空间和写入性能,因此需要根据实际情况权衡利弊,只创建必要的索引。
- 优化聚合函数:在使用聚合函数时,如 SUM、AVG、COUNT 等,应尽量减少不必要的计算。可以通过合理设计查询语句,避免重复计算。在计算一段时间内的平均电流时,可以先根据时间范围过滤数据,再进行聚合计算,而不是先对整个数据表进行聚合计算,再过滤结果。这样可以减少计算量,提高查询效率。还可以使用 TDengine 提供的一些优化函数,如FIRST、LAST等,这些函数在处理时序数据时具有更高的效率。
4.5.2 缓存策略
TDengine 的缓存机制可以将频繁访问的数据存储在内存中,减少数据读取时间,提高查询性能。了解和利用好缓存策略,能够进一步优化查询性能。
- 查询缓存:TDengine 会自动缓存查询结果,当相同的查询再次执行时,可以直接从缓存中获取结果,而不需要重新执行查询。为了充分利用查询缓存,应尽量保持查询语句的一致性。在编写查询代码时,避免使用动态生成的查询语句,除非必要。如果查询条件经常变化,缓存的命中率会降低,影响查询性能。可以将一些常用的查询语句进行封装,确保每次查询时语句的一致性,提高缓存的命中率。
- 数据缓存:除了查询缓存,TDengine 还会缓存数据块。当查询数据时,如果所需的数据块已经在缓存中,就可以直接从缓存中读取,而不需要从磁盘读取。为了提高数据缓存的命中率,应根据业务需求合理调整缓存参数,如 cache 的大小。在数据访问模式比较集中的场景中,可以适当增大 cache 的大小,以缓存更多的数据块。还可以通过分析数据的访问频率和热点数据,优化缓存的管理策略,将热点数据优先缓存到内存中,提高查询性能。
五、案例分析
5.1 案例背景介绍
某大型智能工厂,拥有数千台生产设备,这些设备通过传感器实时采集大量的生产数据,如温度、压力、转速等。数据采集频率高,每秒每个设备可产生多条数据。工厂利用这些数据进行设备状态监控、生产效率分析以及质量控制等业务。
随着工厂业务的不断拓展,设备数量逐渐增加,数据量呈爆发式增长。原本运行良好的 TDengine 数据库系统开始出现性能问题。数据写入速度明显变慢,部分设备的数据甚至出现延迟写入的情况,这使得实时监控和预警功能受到影响,无法及时发现设备的异常状态。查询响应时间也大幅增加,一些复杂的生产数据分析查询需要等待数分钟才能得到结果,严重影响了生产决策的及时性和准确性。这些性能问题给工厂的生产运营带来了极大的困扰,急需进行性能监控与调优。
5.2 性能监控过程
为了找出性能问题的根源,工厂技术团队首先使用 taosKeeper 和 TDinsight 对 TDengine 进行全面的性能监控。通过 taosKeeper 配置,使其定期采集 TDengine 的各项性能指标,并将数据存储到 TDengine 的 log 数据库中。然后,在 Grafana 中导入 TDinsight 仪表板,将采集到的数据进行可视化展示。
经过一段时间的监控,从可视化图表中发现,CPU 使用率在数据写入高峰时段经常达到 90% 以上,内存使用率也长期保持在 80% 左右,磁盘 I/O 读写繁忙,网络带宽利用率较高。在查询性能方面,复杂查询的响应时间随着数据量的增加而急剧上升。通过进一步分析监控数据,发现写入缓慢主要是由于写入线程数不足,导致数据在内存中积压,无法及时落盘;查询超时则是因为部分查询语句没有合理利用索引,导致全表扫描,消耗了大量的系统资源。
5.3 调优措施实施
针对性能监控发现的问题,技术团队采取了一系列调优措施。
- 硬件升级:增加服务器的 CPU 核数,从原来的 8 核升级到 16 核,以提高数据处理能力;将内存容量从 32GB 扩展到 64GB,为数据缓存和处理提供更充足的空间;更换高速 SSD 磁盘,提升磁盘 I/O 性能,加快数据的读写速度。
- 参数调整:在 TDengine 的配置文件中,将写入线程数numOfCommitThreads从默认的 4 增加到 8,以加快数据落盘速度;增大缓存参数cache的大小,从原来的 10GB 调整为 20GB,提高数据查询的命中率;调整buffer的大小,使其能够容纳更多的缓存数据,减少磁盘 I/O 操作。
- 数据库设计优化:对表结构进行优化,根据设备类型和数据采集频率,合理划分超级表和子表。对于数据采集频率相同、设备类型相似的数据,归为同一个超级表,每个设备的数据作为子表,这样可以提高数据管理和查询的效率。重新设计数据分区策略,按时间和设备 ID 进行双重分区,既便于按时间范围查询数据,又能快速定位到特定设备的数据,提高查询性能。
- 写入性能优化:在数据写入代码中,采用批量写入的方式,将多条数据组合成一个批量写入请求,减少写入操作的次数,提高写入效率。引入多线程写入机制,利用服务器的多核资源,同时进行多个写入操作,进一步提升写入速度。
- 查询性能优化:对查询语句进行全面审查和优化,避免全表扫描。在查询条件中尽量使用索引字段,为经常用于查询的字段创建索引。优化聚合函数的使用,减少不必要的计算,提高查询效率。调整查询缓存策略,增加查询缓存的大小和有效期,提高查询缓存的命中率。
5.4 调优效果评估
经过一段时间的运行和监测,对比调优前后的性能指标,发现调优效果显著。写入速度大幅提升,从原来每秒写入数千条数据提升到每秒写入数万条数据,基本能够满足设备实时数据采集的需求,数据延迟写入的问题得到了有效解决。查询响应时间明显缩短,复杂查询的响应时间从原来的数分钟缩短到数秒,简单查询几乎可以实时返回结果,大大提高了生产数据分析的效率和及时性,为生产决策提供了有力支持。CPU 使用率在高峰时段也能保持在 70% 以下,内存使用率稳定在 60% 左右,磁盘 I/O 和网络带宽的利用率也处于合理范围内,系统整体性能得到了极大的提升,能够稳定高效地支持工厂的生产运营。
六、总结与展望
6.1 总结性能监控与调优要点
在本次关于 TDengine 性能监控与调优的探索中,我们深入了解了多个关键方面。监控指标上,CPU 使用率、内存使用率、磁盘 I/O、网络 I/O 以及查询与写入性能,这些指标是判断 TDengine 运行状况的重要依据,它们如同人体的各项生理指标,反映着系统的健康程度。借助 taosKeeper 和 TDinsight 等工具,我们能够全面、准确地获取这些指标,并通过 Grafana 将其可视化,使复杂的数据变得直观易懂,方便我们及时发现性能问题。
在性能问题排查时,从硬件层面的 CPU、内存、磁盘资源检查,到网络层面的连接稳定性测试,再到配置参数层面的精细调整以及业务逻辑层面的合理性审查,每一个环节都至关重要,需要我们层层递进,抽丝剥茧,才能找到问题的根源。
调优措施更是涵盖了硬件、配置参数、数据库设计、写入和查询性能等多个维度。硬件层面的升级为 TDengine 提供了更强大的运行基础;配置参数的合理调整使其能够更好地适应不同业务场景;优化数据库设计,如合理选择数据类型、设计超级表与子表关系以及制定科学的数据分区策略,能够提高数据的存储和查询效率;而写入性能优化中的批量写入和多线程写入,以及查询性能优化中的查询语句优化和缓存策略的运用,都能显著提升 TDengine 的整体性能。
6.2 展望未来发展趋势
展望未来,TDengine 在性能优化方面有着广阔的发展空间。在新技术应用上,随着人工智能和机器学习技术的不断发展,TDengine 有望引入相关算法,实现智能化的性能优化。通过对大量历史性能数据的学习和分析,自动调整配置参数,预测性能瓶颈,并提前采取优化措施,从而实现系统性能的自优化和自调整。随着分布式计算技术的不断演进,TDengine 可能会进一步优化其分布式架构,更好地利用分布式资源,提高集群的扩展性和性能稳定性,以应对更加复杂和大规模的业务场景。
在功能改进方面,TDengine 可能会增加更多丰富的数据类型和函数,以满足不同行业和业务场景的多样化需求。在金融领域,可能需要支持更多复杂的金融数据类型和计算函数;在物联网领域,对于传感器数据的处理可能需要更专业的函数和算法。TDengine 还可能会加强与其他大数据工具和平台的集成,如与 Hadoop、Spark 等的深度融合,实现数据的无缝流转和协同处理,进一步提升数据处理和分析的效率。相信随着技术的不断进步和创新,TDengine 将在时序数据处理领域发挥更加重要的作用,为各行业的数字化发展提供更强大的支持。
七、参考资料
- TDengine 官方文档:TDengine 文档 | TDengine 文档 | 涛思数据,提供了全面的产品介绍、安装指南、使用教程以及详细的技术文档,是深入了解 TDengine 的重要资料。
- TDengine GitHub 仓库:https://github.com/taosdata/TDengine,包含了 TDengine 的源代码、社区讨论、问题反馈等内容,有助于跟踪项目的最新进展和参与社区开发。
- 《TDengine 性能优化最佳实践》:https://www.taosdata.com/blog/2023/08/15/20230815.html,详细介绍了 TDengine 性能优化的具体方法和案例分析,为实际操作提供了宝贵的经验。
- TDengine 社区论坛:https://forum.taosdata.com/,是 TDengine 用户交流和分享经验的平台,在这里可以获取到其他用户在使用过程中遇到的问题及解决方案,以及与 TDengine 技术团队进行沟通交流。
相关文章:
TDengine 性能监控与调优实战指南(二)
四、TDengine 性能调优实战 4.1 硬件层面优化 硬件是 TDengine 运行的基础,其性能直接影响着 TDengine 的整体表现。在硬件层面进行优化,就如同为高楼大厦打下坚实的地基,能够为 TDengine 的高效运行提供有力支持。 CPU:CPU 作…...
Linux `init 5` 相关命令的完整使用指南
Linux init 5 相关命令的完整使用指南—目录 一、init 系统简介二、init 5 的含义与作用三、不同 Init 系统下的 init 5 行为1. SysVinit(如 CentOS 6、Debian 7)2. systemd(如 CentOS 7、Ubuntu 16.04)3. Upstart(如 …...
uni-app中map的使用
uni-app中map的使用 一、基本使用步骤 1. 引入 map 组件 在 .vue 文件的 template 中直接使用 <map> 标签: <template><view><map :latitude"latitude" :longitude"longitude" :markers"markers" style&quo…...
备战2025年全国信息素养大赛图形化大赛——绘制雪花
以上题目点击下方地址,可查看答案或者在线编程~ 绘制雪花_scratch_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/scratch/show-5775.html?_shareid3 程序演示可点击下方地址,支持源码和素材获取,方便高效ÿ…...
1Panel - 基于Web的Linux服务器管理工具
本文翻译整理自:https://github.com/1Panel-dev/1Panel 文章目录 一、关于 1Panel相关链接资源关键功能特性 二、安装系统要求安装脚本 三、基本使用(快速开始)1、快速安装2、访问面板 四、界面展示五、专业版六、安全信息感谢 一、关于 1Pan…...
基于SpringAI Alibaba实现RAG架构的深度解析与实践指南
一、RAG技术概述 1.1 什么是RAG技术 RAG(Retrieval-Augmented Generation)检索增强生成是一种将信息检索技术与生成式AI相结合的创新架构。它通过以下方式实现智能化内容生成: 知识检索阶段:从结构化/非结构化数据源中检索相关…...
SpringBoot Actuator指标收集:Micrometer与Prometheus集成
文章目录 引言一、Spring Boot Actuator基础二、Micrometer简介与集成三、基本指标收集与配置四、自定义业务指标实现五、与Prometheus集成六、实战案例:API性能监控总结 引言 在现代微服务架构中,监控应用程序的健康状况和性能指标变得至关重要。Sprin…...
Spring Boot 集成 Kafka 及实战技巧总结
Spring Boot 集成 Kafka 及实战技巧总结 一、Spring Boot 集成 Kafka 添加依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>配置 Kafka 在 application.yml 中配置生产…...
LeetCode hot 100—分割等和子集
题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。…...
JUC复习及面试题学习
资源来自沉默王二、小林coding、竹子爱熊猫、代码随想录 一、JUC 1、进程与线程 进程是对运行程序的封装,是系统进行资源调度和分配的最小单位。 线程是进程的子任务,是CPU调度分配的基本单位 不同的进程之间很难数据共享,同进程下的不同线…...
The_Planets_Earth靶场笔记(VulnHub)
环境说明: kali地址:192.168.144.128 靶机地址:192.168.144.181 靶机网卡改为NAT模式。 靶机下载地址: https://download.vulnhub.com/theplanets/Earth.ova 一.信息收集: 1.主机探测: 使用如下命令…...
dawgctf 2025 writeup
dawgctf 2025 writeup 赛事信息pwnJust Parry Lol miscDont Touch My FoneThe BirdsMystery Signal IinternsProjectSuspicious scriptSpectral SecretsCaddyshack forensicsKeeping on ScheduleJust Packets CryptoCipher For Good osintEs ist alles in ButterLook Long and …...
机器学习(神经网络基础篇)——个人理解篇6(概念+代码)———参数优化篇
1 在声明一个类中,构建一个属于类的函数,前面为什要加上“self”? 就像下面这一串代码: class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std0.01):# 初始化权重self.params {}self.p…...
AI速读:解锁LLM下Game Agent的奇妙世界
在 AI 浪潮中,大语言模型(LLMs)正重塑游戏智能体格局。想知道基于 LLMs 的游戏智能体如何运作,在各类游戏中有何惊艳表现,未来又将走向何方? 大型语言模型(LLMs)的兴起为游戏智能体的…...
个人所得税
文章目录 一、名词解释二、个人所得税计算方法 (举例)1.累计预扣预缴应纳税所得额、本期应预扣预缴税额2.个人所得税预扣率表一3.个人所得税计算举例 三、专项附加扣除政策介绍四、年度汇算清缴政策介绍五、常见问答 一、名词解释 累计预扣法是指扣缴义务人在一个纳税年度内预…...
DEA-Net:基于细节增强卷积和内容引导注意力的单图像去雾
IEEE TIP 2024 | DEA-Net:基于细节增强卷积和内容引导注意力的单图像去雾 DEA-Net: Single image dehazing based on detail-enhanced convolution and content-guided attention paper name: DEA-Net: Single image dehazing based on detail-enhanced convolutio…...
StringEscapeUtils:给你的字符串穿上“防弹衣“——转义工具类深度解析
各位代码勇士们好!今天我们要聊的是Apache Commons Lang3中的StringEscapeUtils工具类。如果说StringUtils是瑞士军刀,那StringEscapeUtils就是你的字符串保镖,专门负责在各种危险场合保护你的字符串安全! 一、为什么需要字符串转…...
Sharding-JDBC 系列专题 - 第二篇:广播表(Broadcast Tables)
Sharding-JDBC 系列专题 - 第二篇:广播表(Broadcast Tables) 本系列专题旨在帮助开发者深入掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第二篇文章,将详细讲解 广播表(Broadcast Tables) 的概念、配置、使用场景、工作原理以及实战案例。广播表…...
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRect)
文章目录 一、构造与初始化方法二、坐标与尺寸获取三、坐标与尺寸设置四、几何运算方法五、移动与调整方法六、状态判断方法七、类型转换方法八、操作符重载九、静态方法十、特殊方法附录方法速查表注意的问题交集和并集图解 📘 PySide6.QtCore.QRect 使用整数精度定…...
常见的页面报错
目录 1、 405报错,方法不允许 2、 404报错,未找到资源 404报错的两种可能: 1、前端找不到后端的资源: 2、后端找不到返回的资源: 3、 400报错,错误的请求 后端返回的数据类型与前端不匹配 前端传递的参…...
人机共跑,马拉松人型机器人同跑
马拉松比赛对人形机器人来说,是一场对硬件极限的测试,涉及机械、传感器、能源管理等多个方面。用户问的是硬件方面的考察和改进,这意味着我的回答需要聚焦于硬件性能,而不是算法或软件的优化。 对人形机器人硬件的考研 机械结构与…...
ES6 第一讲 变量定义 堆与栈 字符串的扩展和数值型的扩展
文章目录 1.ES6变量定义2.ES6堆和栈3.字符串的扩展3.1 模板字符串3.2 判断是否以指定的字符串开头或结尾3.3 字符串重复输出3.4 填充方法3.5 去除前后字符串空格3.6 返回参数指定位置的字符 4. 数值型的扩展4.1 二进制0B 八进制0O4.2 判断是否是一个无穷大的数字 (判…...
Linux 动、静态库的实现
前言:当我们写了一段代码实现了一个方法,如果我们不想把方法的实现过程暴露给别人看,可以把代码打包成一个库,其中形成后缀为.a的是静态库,后缀为.so的为动态库;当别人想使用你的方法时,把打包好…...
linux多线(进)程编程——(9)信号量(二)
前言 上一篇文章我们讲解了信号量的基础用法,这一篇文章我们承接上面的内容,给大家进一步提升对信号量的理解。如果没有看过上一篇文章,请大家移步linux多线(进)程编程——(9)信号量(一) 案例…...
编码器---正交编码器
一、正交编码器定义与核心作用 正交编码器(Orthogonal Encoder),又称增量式编码器,是一种通过输出两路相位差90的脉冲信号(A相、B相)来测量旋转角度、速度和方向的传感器。其核心优势是通过A/B相的脉冲顺序…...
【HDFS入门】HDFS故障排查与案例分析:从日志分析到实战解决
目录 1 HDFS故障排查概述 2 三大常见故障类型解析 2.1 块丢失问题处理流程 2.2 副本不足问题架构 2.3 DataNode无法启动诊断 3 日志分析实战技巧 3.1 NameNode日志分析框架 3.2 DataNode日志分析流程 4.1 实战案例分析 4.2 集群性能突然下降 4.2 数据读写异常处理 …...
爆肝整理!Stable Diffusion的完全使用手册(二)
继续介绍Stable Diffusion的文生图界面功能。 往期文章详见: 爆肝整理!Stable Diffusion的完全使用手册(一) 下面接着对SD的文生图界面的进行详细的介绍。本期介绍文生图界面的截图2,主要包含生成模块下的采用方法、调度类型、迭…...
经典算法 表达式求值
表达式求值 问题描述 给你一个只包含、-、*、/、0、1、2、3、4、5、6、7、8、9的字符串求出该字符串所代表的表达式的值。这里的除法,为了简便,为整数除法,所以答案一定也是一个整数。保证0不作被除数。 示例输入 (16*(141))((13)*(74))*…...
【Java】接口interface学习
参考资料::黑马程序员入门到飞起上 1 概述 在学习完抽象类后,我们了解到抽象类中既可以包含抽象方法,也能有普通方法、构造方法以及成员变量等。而接口则是一种更为彻底的抽象形式。在JDK7及之前的版本中,接口内全部为抽象方法&…...
数据结构实验7.1:二叉树的遍历
文章目录 一,实验目的二,实验描述三,基本要求四,算法分析五,实验操作六,示例代码七,运行效果一,实验目的 深入理解树与二叉树的基本概念,包括节点、度、层次、深度等,清晰区分二叉树与一般树的结构特点,为后续学习和应用打下坚实基础。熟练掌握用递归方法实现二叉树…...
seata db模式,nacos注册中心,spring boot ,spring cloud ,jdk1.8 完成的配置步骤
1. 环境准备 确保以下环境已经安装并正常运行: JDK 1.8MySQL(或其他支持的数据库)Nacos Server(用于注册中心和配置中心)Seata Server 2. 配置 Seata Server (1) 下载并解压 Seata 从 Seata 官方 GitHub 下载最新版…...
C++进阶-多态
文章目录 C进阶--多态概念多态的定义及实现多态的构成条件实现多态的两个重要条件虚函数虚函数的重写及覆盖协变析构函数的重写(面试被问及最好需要举例说明)override和final关键字重载,重写(覆盖),隐藏&am…...
Linux教程-常用命令系列三
文章目录 1. 网络安全常用命令1. su (Switch User)2. chmod (Change Mode)3. chown (Change Owner)4. ps (Process Status)5. who6. top7. free8. kill9. gedit10. find总结 2. 字符串显示命令2.1 基本语法2.2 常用选项2.3 核心功能与示例2.3.1 输出字符串2.3.2 输出变量2.3.3 …...
GIS开发笔记(9)结合osg及osgEarth实现三维球经纬网格绘制及显隐
一、实现效果 二、实现原理 按照5的间隔分别创建经纬线的节点,挂在到组合节点,组合节点挂接到根节点。可以根据需要设置间隔度数和线宽、线的颜色。 三、参考代码 //创建经纬线的节点 osg::Node *GlobeWidget::createGraticuleGeometry(float interv…...
nuxt3前端开发以及nuxt3和nuxt2项目的详细差异点
以下是 Nuxt 3 前端开发的详细指南以及与 Nuxt 2 的核心差异总结,涵盖配置、开发模式、API 变化等关键方面: 一、Nuxt 3 前端开发核心要点 1. 项目初始化 # Nuxt 3 npx nuxi init <project-name> cd <project-name> npm install npm run dev# Nuxt 2 (对比) np…...
Android学习总结之APK打包流程
一、预处理阶段(编译前准备) 1. AIDL 文件处理(进程间通信基础) 流程: 用于实现 Android 系统中不同进程间的通信(IPC)。在项目构建时,AIDL 编译器会将 .aidl 文件编译为 Java 接口…...
java面试篇(常见的集合底层原理)
集合 1、arraylist源码分析 三种构造方法: 扩容的逻辑: 2、ArrayList的底层实现原理是什么? ArrayList listnew ArrayList(10)中的list扩容几次 3、如何实现数组和List之间的转换 4、LinkedList和arraylist的区别 5、hashmap的实现原理 二叉…...
RAG框架精选2
原文链接:https://i68.ltd/notes/posts/20250406-llm-rag2/ 清华Hyper-RAG 使用超图驱动的RAG对抗LLM幻觉论文链接:https://arxiv.org/pdf/2504.08758项目仓库:https://github.com/iMoonLab/Hyper-RAG清华Hyper-RAG:利用超图建模高阶关系,让DeepSeek/Q…...
Redis进阶学习
什么是Redis? Redis是一个key-value结构的非关系型数据库,将数据存储在内存中,结构简单(五种数据结构:string、list、set、zset、hash),数据读写速度快,还可以将数据持久化到硬盘上。…...
【读书笔记·VLSI电路设计方法解密】问题63:为什么可测试性设计对产品的财务成功至关重要
可测试性设计至关重要,因为我们不希望将劣质或故障部件交付给客户。向客户交付过多不良部件意味着财务灾难,更会损害企业声誉并导致商业机会流失。 若设计中未嵌入可测试性设计(DFT),区分良品与不良品的唯一方法就是由应用工程师或客户在实际应用环境中测试芯片。此时芯片…...
Federated Weakly Supervised Video Anomaly Detection with Multimodal Prompt
标题:联邦弱监督视频异常检测的多模态提示方法 原文链接:https://ojs.aaai.org/index.php/AAAI/article/view/35398 源码链接:https://github.com/wbfwonderful/Fed-WSVAD 发表:AAAI-2025 摘要(Abstract) …...
计算机视觉与深度学习 | LSTM原理,公式,代码,应用
LSTM(长短期记忆网络)详解 一、原理 LSTM(Long Short-Term Memory)是RNN的改进版本,通过引入门控机制(输入门、遗忘门、输出门)和细胞状态(Cell State),有效解决传统RNN的梯度消失/爆炸问题,擅长捕捉长距离依赖关系。 核心思想: 细胞状态(C_t):贯穿整个时间步…...
UI界面工程,如何使用控制台
我们通常会使用print函数向控制台输出调试信息。但创建UI界面工程时,默认不会显示控制台。 通过如下方法切换到控制台 项目属性—链接器—系统—子系统—窗口改为控制台...
mysql——基础知识
关键字大小写不敏感 查看表结构中的 desc describe 描述 降序中的 desc descend 1. 数据库的操作 1. 创建数据库 create database 数据库名;为防止创建的数据库重复 CREATE DATABASE IF NOT EXISTS 数据库名;手动设置数据库采用的字符集 character set 字符集名;chars…...
UE虚幻4虚幻5动画蓝图调试,触发FellOutOfWorld事件和打印输出,继续DeepSeek输出
找到了一个pdf,本来想写个翻译的,但还是算了,大概看了下,这类文档很全面,内容很多,但都不是我要的,我想要一个动画蓝图,搜索Montage,或者Anim 只占了一行(几百…...
52单片机LED实验
文章目录 前言点亮一个LEDLED闪烁 LED灯亮灭交替LED流水灯 前言 我所用的板子是普中的STC89C52RC,创建文件的过程中如果你发现keil文件找不到单片机依赖,那怎么办呢 下面从创建新项目讲起 首先打开keil软件,点击project new一个新的projec…...
【C++详解】C++入门(一)命名空间、缺省参数、函数重载
文章目录 一、命名空间命名空间的基本特性命名空间的使用 二、C输入输出用法三、缺省参数(默认参数)定义用法 四、函数重载 一、命名空间 命名空间的基本特性 #include <stdio.h> #include <stdlib.h>int rand 10;int main() {// 编译报错:error C23…...
AWS Linux快速指南:5分钟搭建多用户图形界面
一、概述 本指南将帮助您在AWS上快速部署一个支持多用户、带图形界面和浏览器的Linux环境。我们将使用Ubuntu Server作为基础,配合轻量级的Xfce桌面环境和VNC服务。同时,我们还将提供不同用户规模下的实例规格推荐。 二、实例规格推荐 根据您的用户规模,我们推荐以下EC2实例…...
kotlin,编码、解码
kotlin写程序确实简洁,就是函数式编程对我这种用惯了过程的,换思想有难度。package org.exampleimport java.io.File import java.io.FileNotFoundExceptionval byteToHanzi mapOf(0x00 to "凡", 0x01 to "周", 0x02 to "张&q…...
从零创建 Docker 镜像(基于 OCI 格式)
更现代的 OCI 镜像格式,采用了 OCI Image Format Specification,其中文件引用使用 blobs/sha256/<hash> 的形式,层和配置存储在 blobs/sha256/ 目录下,并且包含 LayerSources 字段。这种格式在较新的 Docker 版本和 OCI 兼容…...