• [专题汇总] 2025年开年的第一篇合集来了。速进
    大家好,2025年开年的第一篇合集,本次带来的是Python,Java,MySql,Golang,JSON,等等希望可以帮到大家。1.Python判断for循环最后一次的方法【转】https://bbs.huaweicloud.com/forum/thread-0248173698858425071-1-1.html2.使用Python实现高效的端口扫描器【转】https://bbs.huaweicloud.com/forum/thread-0248173699028101072-1-1.html3.使用Python实现操作mongodb详解【转】https://bbs.huaweicloud.com/forum/thread-02109173699263711070-1-1.html4.一文详解Python中数据清洗与处理的常用方法【转】https://bbs.huaweicloud.com/forum/thread-02109173699342905071-1-1.html5.Go中sync.Once源码的深度讲解【转】https://bbs.huaweicloud.com/forum/thread-0271173699402065058-1-1.html6.从源码解析golang Timer定时器体系【转】https://bbs.huaweicloud.com/forum/thread-0251173701525255062-1-1.html7.golang1.23版本之前 Timer Reset方法无法正确使用【转】https://bbs.huaweicloud.com/forum/thread-02127173701584637057-1-1.html8.Python文件读写实用方法小结【转】https://bbs.huaweicloud.com/forum/thread-02104173701685566070-1-1.html9.mysql外键创建不成功/失效如何处理【转】https://bbs.huaweicloud.com/forum/thread-02109173701958630072-1-1.html10.Redis的Zset类型及相关命令详细讲解【转】https://bbs.huaweicloud.com/forum/thread-02109173702031434073-1-1.html11.大数据小内存排序问题如何巧妙解决【转】https://bbs.huaweicloud.com/forum/thread-02127173702077058058-1-1.html12.Redis多种内存淘汰策略及配置技巧分享【转】https://bbs.huaweicloud.com/forum/thread-0272173702166312062-1-1.html13.MySQL通过binlog实现恢复数据【转】https://bbs.huaweicloud.com/forum/thread-02109173702268081074-1-1.html14.MySQL如何将一个表的字段更新到另一个表中【转】https://bbs.huaweicloud.com/forum/thread-0272173702328248063-1-1.html15.JSON字符串转成java的Map对象详细步骤【转】https://bbs.huaweicloud.com/forum/thread-02109173702572327075-1-1.html
  • [技术干货] Redis多种内存淘汰策略及配置技巧分享【转】
    前言Redis 是一个高性能的内存数据库,广泛应用于缓存系统、消息队列等场景。当 Redis 的内存达到限制时,需要根据一定的策略来淘汰数据,以便腾出空间给新数据。本文将深入解析 Redis 的内存淘汰机制,帮助更好地配置 Redis,应对不同的内存需求。一、什么是 Redis 的内存淘汰机制?Redis 默认将所有数据存储在内存中,当内存满了且没有设置淘汰策略时,Redis 将无法接受新的写入操作。因此,Redis 提供了一些内存淘汰机制,用于自动删除部分数据,为新数据腾出空间。二、Redis 内存淘汰策略Redis 提供了 8 种内存淘汰策略,允许用户根据实际需求灵活选择。以下是每种策略的详细介绍:1. noeviction(拒绝写入,保留所有数据)当内存达到最大限制时,Redis 会拒绝新的写入操作,确保现有数据不被淘汰。适用于对数据完整性要求极高的场景,但可能导致服务不可用。示例配置:maxmemory 100mbmaxmemory-policy noeviction此时,Redis 会在内存使用超过 100MB 后拒绝所有写入操作,并返回OOM command not allowed错误。2. volatile-lru(最少使用淘汰,仅限过期数据)仅淘汰设置了 过期时间(TTL)的键,使用 LRU(Least Recently Used,最近最少使用)算法删除最久未使用的数据。适用于需要定期清理过期缓存的场景。示例配置:maxmemory 100mbmaxmemory-policy volatile-lru3. allkeys-lru(最少使用淘汰,适用于所有数据)适用于所有键(无论是否设置过期时间)。Redis 使用 LRU 算法淘汰最久未使用的键。适用于缓存场景,确保热点数据得以保留。示例配置:maxmemory 200mbmaxmemory-policy allkeys-lru
  • [技术干货] Redis的Zset类型及相关命令详细讲解【转】
    Zset简介有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,着使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个分数。ZADD添加或者更新指定的元素以及关联的分数到 zset 中,分数应该符合 double 类型,+inf/-inf 作为正负极限也是合法的。语法1ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]ZADD 的相关选项:• XX:仅仅⽤于更新已经存在的元素,不会添加新元素。• NX:仅⽤于添加新元素,不会更新已经存在的元素。• CH:默认情况下,ZADD 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。• INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。时间复杂度:O(log(N))返回值:本次添加成功的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 1 "uno"(integer) 1redis> ZADD myzset 2 "two" 3 "three"(integer) 2redis> ZRANGE myzset 0 -1 WITHSCORES1) "one"2) "1"3) "uno"4) "1"5) "two"6) "2"7) "three"8) "3"ZCARD获取⼀个 zset 的基数(cardinality),即 zset 中的元素个数。语法ZCARD key时间复杂度:O(1)返回值:zset 内的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZCARD myzset(integer) 2
  • [技术干货] Redis大Key问题全解析-转载
    1. 引言1.1 什么是Redis大Key?Redis大Key是指单个Key对应的数据量过大,占用过多的内存或导致操作耗时较长的现象。大Key可以是以下几种常见数据类型中的任意一种:String类型:单个字符串的长度过大。List类型:包含大量元素的列表。Hash类型:存储大量字段的哈希表。Set或ZSet类型:存储大量成员的集合或有序集合。大Key并不直接导致系统问题,但其潜在影响和风险非常显著,尤其在生产环境中。1.2 Redis大Key的危害性能瓶颈:对大Key的读写操作可能占用过多的CPU资源,导致其他操作延迟。阻塞问题:一次性删除大Key或迁移大Key时,Redis可能出现阻塞,从而影响整个服务。内存压力:大Key会占用大量内存,增加内存碎片化的风险,并可能触发Redis的内存淘汰机制。恢复缓慢:当需要从快照(RDB)或日志(AOF)中加载数据时,大Key会显著延长恢复时间。1.3 为什么需要关注大Key问题?在生产环境中,Redis被广泛用作缓存和数据库,如果忽略大Key问题,可能导致以下后果:线上事故频发:由于Redis本身是单线程模型,大Key的操作会阻塞主线程,影响所有客户端请求。业务中断:高延迟甚至不可用的情况会对业务造成直接损失。运维复杂度增加:需要额外的监控和排查,增加了运维负担。2. Redis大Key引发的线上事故场景2.1 常见事故场景描述操作大Key导致Redis阻塞Redis是单线程执行命令的,在操作大Key(如读取、更新或删除)时,单次命令可能需要较长时间完成,阻塞其他客户端请求。例如:使用DEL删除一个包含数百万元素的List或Set时,操作可能耗时几秒甚至更久,导致其他请求无法响应。大Key迁移时的性能问题在Redis进行主从同步或数据迁移时,大Key的传输会占用大量带宽和时间。如果迁移操作与正常业务请求同时进行,可能导致Redis服务性能大幅下降,甚至引发业务中断。慢查询和超时的影响对大Key执行复杂操作(如LRANGE、HGETALL、ZRANGEBYSCORE)时,操作时间会随着数据量的增长线性甚至指数级增加,可能触发慢查询或请求超时。例如:一次性从一个包含百万条数据的List中获取范围数据,容易导致应用程序响应缓慢。2.2 事故表现及影响业务卡顿用户请求无法及时得到响应,表现为接口延迟增加甚至超时。对于高并发场景,这种情况会进一步放大,导致更多请求堆积。系统不可用阻塞问题可能让整个Redis实例无法响应请求,导致相关业务完全瘫痪。如果Redis作为缓存使用,缓存不可用会给后端数据库带来极大压力,可能进一步引发数据库瓶颈。难以快速恢复在线上恢复过程中,删除或迁移大Key会进一步延长恢复时间。大Key也会导致Redis内存碎片增加,可能需要触发MEMORY FRAGMENTATION的手动优化,进一步增加停机时间。3. 如何发现Redis大Key在排查Redis性能问题时,发现和定位大Key是解决问题的关键步骤。以下是一些常用的方法和工具,可以帮助识别和诊断Redis中的大Key。1. 使用Redis命令行工具MEMORY USAGE作用:返回指定Key的内存占用大小(以字节为单位)。示例:MEMORY USAGE mykey1输出结果会显示该Key的大小,通过与其他Key对比,可以发现异常占用内存的大Key。RANDOMKEY作用:随机返回一个Key,用于抽样分析。示例:RANDOMKEY1配合MEMORY USAGE或DEBUG OBJECT命令,可以抽样检查Key的大小和属性。DEBUG OBJECT作用:提供关于Key的详细调试信息,包括编码方式和元素个数。示例:DEBUG OBJECT mykey1输出信息中的serializedlength字段可作为判断Key大小的重要依据。SCAN命令作用:增量遍历Redis中的Key,适合在大数据量环境下使用。示例:SCAN 0 MATCH * COUNT 1001遍历过程中结合MEMORY USAGE或其他分析工具,可以识别出大Key。2. 使用监控工具Redis自带的慢查询日志配置SLOWLOG参数,记录执行时间较长的命令。示例:SLOWLOG GET 101通过分析慢查询日志,可以定位哪些操作耗时过长,并进一步确认是否因大Key导致。第三方监控平台Prometheus + Grafana:通过Redis Exporter收集监控数据,设置内存占用、命令执行时间等指标的报警规则。Datadog:可视化展示Redis实例的性能数据,包括每个Key的内存占用。阿里云、腾讯云等云监控工具:对Redis实例进行实时分析,快速定位异常Key。专用大Key扫描工具开源工具如redis-rdb-tools:通过分析RDB文件识别大Key。在线扫描工具:通过API或脚本对Key逐个检查,生成大Key列表。3. 自定义脚本扫描大Key编写脚本遍历Redis中的Key,并分析每个Key的大小和类型。例如,以下Python脚本使用redis-py库扫描大Key:import redisdef scan_large_keys(redis_client, size_threshold):    cursor = '0'    while cursor != 0:        cursor, keys = redis_client.scan(cursor=cursor, count=100)        for key in keys:            key_size = redis_client.memory_usage(key)            if key_size and key_size > size_threshold:                print(f"Large key found: {key.decode('utf-8')} - {key_size} bytes")# 连接Redisr = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)scan_large_keys(r, size_threshold=1_000_000)  # 设置阈值为1MB4. 定期巡检和自动化告警定期巡检脚本定时运行扫描脚本,生成大Key报告。将结果输出到日志或发送邮件告警。设置监控阈值配置Redis监控指标,如单个Key的最大内存占用。通过自动化告警(如邮件、短信、钉钉机器人)及时通知异常。4. Redis大Key的解决方案在发现大Key后,关键在于采取有效措施避免其对Redis性能造成影响。以下是Redis大Key问题的常见解决方案,覆盖预防、优化和操作大Key的实际场景。1. 预防大Key的产生设计良好的数据结构在系统设计阶段,避免单个Key存储过多数据:避免过长的字符串:拆分过大的String数据。限制集合大小:通过业务逻辑控制List、Set、Hash等集合类型的元素数量。分层存储:将复杂的数据拆分为多个层次或多个Key,降低单个Key的压力。合理使用TTL(过期时间)为临时性数据设置合理的TTL,防止长期积累造成大Key:EXPIRE mykey 3600  # 设置Key 1小时后过期1写入时检查数据量在写入数据时,检查数据大小或元素数量,提前拦截大Key生成。2. 分解大Key分片存储(Sharding)如果一个List或Set数据量过大,可以通过分片技术将其拆分成多个Key:list:0, list:1, list:2 ...1示例:存储用户订单数据时,可以按照用户ID进行分片。使用哈希表优化存储替代长列表或大字符串:HSET user:1234:name "John" user:1234:age "30"1限制分页查询范围对于需要分页读取的数据,限制返回的范围,例如:LRANGE mylist 0 99  # 每次只读取100条13. 操作大Key的优化分步删除大Key一次性删除大Key可能导致Redis阻塞。可以分步删除大Key,例如使用SCAN命令逐步清理集合:def delete_large_key(redis_client, key):    while True:        elements = redis_client.spop(key, 100)        if not elements:            break12345异步删除大Key如果Redis支持UNLINK命令,可以异步删除大Key,避免阻塞主线程:UNLINK mykey1分段处理大Key对于操作大Key的命令,进行分段执行。例如读取一个大列表时,分批获取数据:LRANGE mylist 0 99LRANGE mylist 100 199124. Redis配置优化调整内存策略配置内存淘汰策略,如volatile-lru或allkeys-lru,以便优先清理过期或较少使用的数据。示例:maxmemory-policy allkeys-lru1合理分配内存确保Redis实例有足够内存避免OOM。定期检查和优化内存碎片,通过INFO MEMORY分析内存使用情况。启用慢查询日志配置慢查询日志参数,定期监控和优化执行耗时的命令:CONFIG SET slowlog-log-slower-than 10000  # 设置慢查询阈值为10ms15. 针对特定场景的优化批量写入优化对于需要批量写入大Key的场景,使用流水线(Pipeline)技术减少网络延迟:pipeline = redis_client.pipeline()for item in data:    pipeline.rpush('mylist', item)pipeline.execute()1234延迟加载策略对大Key采用延迟加载,避免一次性加载到内存。结合Lua脚本可以更高效地处理数据。使用外部存储如果某些数据量极大的Key需要长时间保存,可考虑将其迁移到外部存储(如MySQL、Elasticsearch)。6. 优化案例删除大Key的案例问题:DEL操作卡死Redis实例。解决:使用UNLINK异步删除,或分批删除,避免阻塞。分页查询的优化案例问题:LRANGE操作超时。解决:将请求分批分页,结合Redis流水线批量获取数据。分片存储的案例问题:一个Set类型Key中有数百万数据,导致慢查询。解决:按照业务逻辑对数据进行分片,将其拆分为多个Key,并进行并行操作。5. Redis大Key引发线上事故的实战解决通过对大Key问题的场景化分析,我们总结了几种常见的线上事故案例,以及针对这些问题的实际解决方案。以下是具体的案例分享。案例1:线上服务因大Key删除导致卡顿问题描述某电商系统使用Redis存储用户的浏览记录(List类型),每个用户Key可能包含数十万条数据。系统在清理过期用户数据时,直接执行了以下操作:DEL user:1234:history1结果Redis实例阻塞超过2秒,导致大批请求超时。问题分析DEL命令在删除大Key时,会立即释放所有内存。由于删除过程在主线程中执行,导致其他操作被阻塞。用户浏览记录数据量大,删除时间远超Redis的单线程处理能力。解决方案使用异步删除:UNLINK user:1234:history1异步删除将Key的删除过程交给后台线程,避免主线程阻塞。分批删除大Key:将大列表分片处理,避免一次性操作占用过多资源。def delete_large_key(redis_client, key, batch_size=100):    while True:        redis_client.ltrim(key, batch_size, -1)        if redis_client.llen(key) == 0:            redis_client.delete(key)            break123456案例2:数据迁移中的大Key问题问题描述在进行Redis主从切换时,主节点同步了一个包含数百万条数据的Set类型大Key,导致同步过程持续十几分钟,引发业务延迟。问题分析Redis在主从同步时需要将大Key的数据序列化并通过网络传输。大Key的数据量大,传输时间过长。同步过程中,主从状态不一致,影响了服务稳定性。解决方案分片存储大Key:将Set拆分为多个小Key进行存储:set:0, set:1, set:2 ...1手动迁移分片数据:在迁移数据时,通过脚本分批同步分片Key,避免一次性传输数据过多。RDB文件优化:使用开源工具如redis-rdb-tools对RDB文件进行拆分处理,分批加载数据,减小单次迁移压力。案例3:慢查询导致的服务性能下降问题描述某实时分析系统使用Redis存储用户行为数据,一个Key包含用户当天的所有事件(List类型)。在分析中,执行以下查询时,耗时超过5秒:LRANGE user:events 0 10000001问题分析LRANGE操作的时间复杂度为O(n),随着List长度的增加,查询时间大幅度延长。单线程Redis无法同时处理其他请求,导致全局性能下降。解决方案限制查询范围:改为分页读取数据,每次只获取100条数据:LRANGE user:events 0 991分片存储:按时间段拆分List,将用户行为数据按小时或天分片存储:user:events:20241224, user:events:20241225 ...1外部存储结合分析:对于历史数据,将其从Redis迁移到如Elasticsearch或Hadoop进行分析,Redis仅保留实时数据。案例4:大Key监控引发内存膨胀问题描述某团队定期使用MEMORY USAGE命令扫描大Key,并将扫描结果存储在Redis中。由于记录了大量数据,最终导致Redis内存溢出。问题分析使用Redis存储监控结果时,没有对Key大小和数量进行限制。监控本身引发了内存膨胀和性能下降。解决方案优化监控方式:使用外部存储(如MySQL或文件系统)记录监控结果。控制扫描频率,避免对Redis产生额外压力。结果压缩和过期处理:仅记录大Key的统计摘要而非全量数据。对监控结果设置TTL,确保数据自动清理。定期巡检和告警:使用自动化脚本在离线环境定期扫描大Key,并配置告警规则。6. 经验总结和最佳实践在实际生产环境中,合理应对Redis大Key问题需要结合预防、监控和优化的多种手段。以下是一些经验总结和最佳实践,帮助开发和运维团队更高效地管理Redis系统。1. 日常监控和巡检定期检查大Key使用脚本或监控工具定期扫描Redis中的大Key,发现潜在风险。例如,设置监控脚本对Key的内存占用、元素数量等指标进行检查。监控慢查询配置SLOWLOG并定期分析日志,定位因大Key操作导致的慢查询:CONFIG SET slowlog-log-slower-than 10000  # 设置慢查询阈值为10ms1自动化告警使用Prometheus、Datadog等工具设置内存占用和执行时间的告警阈值。实时监控Redis实例的QPS、内存、阻塞次数等指标,及时发现异常。2. 合理的容量规划限制单个Key的数据量在业务逻辑中明确限制每个Key的最大数据量。例如,限制List类型的最大长度或String类型的最大大小。分片存储设计提前规划分片方案,将可能产生大Key的数据存储为多个小Key。例如,使用Key的前缀(如user:1, user:2)进行分片管理。TTL策略为非永久性数据设置TTL,防止数据长时间堆积形成大Key。3. Redis使用的常见陷阱及规避方法避免一次性操作大Key不建议直接执行如DEL、LRANGE、HGETALL等操作在大Key上。替代方案:分批操作、异步操作(如UNLINK)。操作命令选择优先使用时间复杂度低的命令。例如,尽量避免使用SMEMBERS读取完整集合,可以使用SRANDMEMBER随机读取。预估命令执行时间对高频和复杂的查询操作提前预估时间复杂度,避免高耗时操作影响Redis性能。4. 工具和脚本的高效利用使用开源工具利用redis-rdb-tools分析RDB文件,快速发现大Key。使用redis-cli配合脚本定期扫描、记录大Key。自定义监控脚本定制化脚本结合SCAN、MEMORY USAGE等命令,自动化识别大Key并记录异常。基于Lua脚本的操作优化使用Lua脚本实现复杂操作,降低网络延迟,优化性能。例如:local items = redis.call('LRANGE', KEYS[1], 0, 99)redis.call('LTRIM', KEYS[1], 100, -1)return items5. 团队协作和优化文化开发和运维协作开发团队在数据设计阶段需关注Redis的性能特点,避免不合理的数据模型。运维团队需定期巡检Redis实例,评估存储结构是否符合业务需求。性能优化文化提倡提前预估数据量和操作复杂度,将Redis的性能问题作为系统设计的重要考量。将Redis大Key优化纳入系统性能优化的日常工作。7. 附录在本文中提到的解决方案和工具中,很多都需要具体的脚本或命令支持。本附录提供了常用的Redis大Key排查和优化相关脚本示例,以及一些推荐的学习资料和工具链接。7.1 常用Redis大Key排查脚本示例批量扫描大Key通过SCAN命令和MEMORY USAGE统计所有Key的内存占用,并输出超出指定阈值的大Key。import redisdef find_large_keys(redis_client, size_threshold=1_000_000):    cursor = 0    while True:        cursor, keys = redis_client.scan(cursor=cursor, count=100)        for key in keys:            size = redis_client.memory_usage(key)            if size and size > size_threshold:                print(f"Large key: {key.decode()} - {size} bytes")        if cursor == 0:            breakif __name__ == "__main__":    r = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)分步删除大Key删除大Key时避免阻塞,逐步清理List或Set的元素。def delete_large_key(redis_client, key, batch_size=100):    while True:        redis_client.ltrim(key, batch_size, -1)        if redis_client.llen(key) == 0:            redis_client.delete(key)            breakif __name__ == "__main__":    r = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)监控大Key生成定时检查Redis实例中的大Key并生成报告。while true; do    redis-cli --scan | while read key; do        size=$(redis-cli memory usage "$key")        if [ "$size" -gt 1000000 ]; then            echo "Large key detected: $key - $size bytes" >> large_keys.log        fi    done    sleep 60done7.2 Redis性能优化的相关参考资料Redis官方文档Redis Commands: 详细介绍了所有Redis命令的用法和性能注意事项。Redis Memory Optimization: 内存优化相关建议。开源工具redis-rdb-tools: RDB文件分析工具,用于快速排查大Key和数据结构问题。redis-cli: Redis自带的命令行工具,可用于排查问题和调试。社区文章和博客Redis大Key问题的排查与解决: 深入解析Redis大Key问题的技术博客。如何优化Redis性能: Redis性能优化的实战案例分享。7.3 Lua脚本示例批量删除大Keylocal key = KEYS[1]local count = tonumber(ARGV[1])for i = 1, count do    redis.call("LPOP", key)endif redis.call("LLEN", key) == 0 then    redis.call("DEL", key)end大Key数据迁移将数据从一个Key迁移到多个分片Key。local source = KEYS[1]local destination = KEYS[2]local batch_size = tonumber(ARGV[1])local items = redis.call("LRANGE", source, 0, batch_size - 1)for i, item in ipairs(items) do    redis.call("RPUSH", destination, item)endredis.call("LTRIM", source, batch_size, -1)7.4 学习和实践建议实验环境搭建使用Docker快速搭建Redis测试环境:docker run --name redis-test -d -p 6379:6379 redis1模拟生产环境中的大Key问题,测试优化方案的效果。团队内部分享定期开展Redis技术分享会,总结大Key排查和优化经验。编写团队内部Redis使用规范文档,避免常见问题。持续学习跟踪Redis的最新版本更新,了解新特性(如UNLINK、MEMORY USAGE)。参与Redis社区讨论,获取更多实战经验。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/weixin_43114209/article/details/144689164
  • [技术干货] 【ES常用查询操作】-转载
    在 Elasticsearch (ES) 中,多条件检索可以通过组合多个查询条件来实现。Elasticsearch 提供了多种查询类型和组合方式,常见的有 bool 查询、must、should、must_not 和 filter 等。以下是一些常见的多条件检索示例。1. 使用 bool 查询bool 查询允许你组合多个查询条件,并指定它们之间的逻辑关系。示例:必须匹配 field1 和 field2,并且可以选择性匹配 field3{"query": {"bool": {"must": [{ "match": { "field1": "value1" } },{ "match": { "field2": "value2" } }],"should": [{ "match": { "field3": "value3" } }],"minimum_should_match": 1}}}在这个示例中,文档必须匹配 field1 和 field2,并且至少匹配 field3 中的一个条件。2. 使用 filter 查询filter 查询用于过滤文档,不计算相关性评分,通常用于结构化数据查询。示例:必须匹配 field1 和 field2,并且过滤 field4{"query": {"bool": {"must": [{ "match": { "field1": "value1" } },{ "match": { "field2": "value2" } }],"filter": [{ "term": { "field4": "value4" } }]}}}在这个示例中,文档必须匹配 field1 和 field2,并且 field4 必须等于 value4。3. 使用 must_not 查询must_not 查询用于排除匹配特定条件的文档。示例:必须匹配 field1,但不能匹配 field2{"query": {"bool": {"must": [{ "match": { "field1": "value1" } }],"must_not": [{ "match": { "field2": "value2" } }]}}}在这个示例中,文档必须匹配 field1,但不能匹配 field2。4. 组合查询示例示例:复杂组合查询{"query": {"bool": {"must": [{ "match": { "field1": "value1" } },{ "range": { "field2": { "gte": 10, "lte": 20 } } }],"should": [{ "match": { "field3": "value3" } },{ "term": { "field4": "value4" } }],"must_not": [{ "term": { "field5": "value5" } }],"filter": [{ "term": { "field6": "value6" } }],"minimum_should_match": 1}}}在这个示例中:文档必须匹配 field1 和 field2 的范围条件。文档应该匹配 field3 或 field4 中的一个条件。文档不能匹配 field5。文档必须匹配 field6。5. 使用 multi_match 查询multi_match 查询允许你在多个字段中搜索相同的关键词。示例:在 field1 和 field2 中搜索 value{"query": {"multi_match": {"query": "value","fields": ["field1", "field2"]}}}在这个示例中,Elasticsearch 将在 field1 和 field2 中搜索 value。6. 使用 nested 查询如果你的文档包含嵌套对象,可以使用 nested 查询。示例:嵌套查询假设你的文档结构如下:{"name": "John","address": {"city": "New York","zipcode": "10001"}}你可以使用 nested 查询来检索嵌套对象中的字段。示例:嵌套查询{"query": {"nested": {"path": "address","query": {"bool": {"must": [{ "match": { "address.city": "New York" } },{ "match": { "address.zipcode": "10001" } }]}}}}}15在这个示例中,查询将检索 address 对象中的 city 和 zipcode 字段。7. 使用 terms 查询terms 查询允许你匹配多个值中的任意一个。示例:匹配 field1 中的多个值{"query": {"terms": {"field1": ["value1", "value2", "value3"]}}}在这个示例中,查询将匹配 field1 中的任意一个值:value1、value2 或 value3。8. 使用 range 查询range 查询允许你匹配数值、日期或字符串范围。示例:匹配 field1 的范围{"query": {"range": {"field1": {"gte": 10,"lte": 20}}}}10在这个示例中,查询将匹配 field1 的值在 10 到 20 之间的文档。9. 使用 exists 查询exists 查询用于匹配包含特定字段的文档。示例:匹配包含 field1 的文档{"query": {"exists": {"field": "field1"}}}7在这个示例中,查询将匹配所有包含 field1 字段的文档。10. 使用 wildcard 查询wildcard 查询允许你使用通配符进行模式匹配。示例:匹配 field1 中的模式{"query": {"wildcard": {"field1": "val*"}}}7在这个示例中,查询将匹配 field1 中以 val 开头的所有值。11. 使用 prefix 查询prefix 查询用于匹配以特定前缀开头的字段值。示例:匹配 field1 中的前缀{"query": {"prefix": {"field1": "val"}}}在这个示例中,查询将匹配 field1 中以 val 开头的所有值。12. 使用 fuzzy 查询fuzzy 查询用于模糊匹配,允许一定程度的拼写错误。示例:模糊匹配 field1{"query": {"fuzzy": {"field1": "value"}}}在这个示例中,查询将模糊匹配 field1 中接近 value 的所有值。13. 使用 regexp 查询regexp 查询允许你使用正则表达式进行模式匹配。示例:正则表达式匹配 field1{"query": {"regexp": {"field1": "val.*"}}}7在这个示例中,查询将匹配 field1 中符合正则表达式 val.* 的所有值。14. 使用 script 查询script 查询允许你使用脚本进行复杂的条件匹配。示例:使用脚本查询{"query": {"script": {"script": {"source": "doc['field1'].value > params.value","params": {"value": 10}}}}}在这个示例中,查询将匹配 field1 的值大于 10 的文档。15. 使用 match_phrase 查询match_phrase 查询用于匹配包含特定短语的文档。示例:匹配 field1 中的短语{"query": {"match_phrase": {"field1": "quick brown fox"}}}在这个示例中,查询将匹配 field1 中包含短语 “quick brown fox” 的文档。16. 使用 match_phrase_prefix 查询match_phrase_prefix 查询用于匹配以特定短语前缀开头的文档。示例:匹配 field1 中的短语前缀{"query": {"match_phrase_prefix": {"field1": "quick brown"}}}在这个示例中,查询将匹配 field1 中以 “quick brown” 开头的短语。17. 使用 geo_distance 查询geo_distance 查询用于匹配在特定地理距离内的文档。示例:匹配在特定地理距离内的文档{"query": {"geo_distance": {"distance": "200km","location": {"lat": 40.7128,"lon": -74.0060}}}}在这个示例中,查询将匹配在距离 (40.7128, -74.0060) 200 公里范围内的文档。18. 使用 geo_bounding_box 查询geo_bounding_box 查询用于匹配在特定地理边界框内的文档。示例:匹配在特定地理边界框内的文档{"query": {"geo_bounding_box": {"location": {"top_left": {"lat": 40.73,"lon": -74.1},"bottom_right": {"lat": 40.01,"lon": -71.12}}}}}在这个示例中,查询将匹配在指定地理边界框内的文档。19. 使用 geo_polygon 查询geo_polygon 查询用于匹配在特定地理多边形内的文档。示例:匹配在特定地理多边形内的文档{"query": {"geo_polygon": {"location": {"points": [{ "lat": 40.73, "lon": -74.1 },{ "lat": 40.01, "lon": -71.12 },{ "lat": 40.73, "lon": -71.12 }]}}}}在这个示例中,查询将匹配在指定地理多边形内的文档。20. 使用 more_like_this 查询more_like_this 查询用于查找与给定文档相似的文档。示例:查找与给定文档相似的文档{"query": {"more_like_this": {"fields": ["field1", "field2"],"like": "text to find similar documents","min_term_freq": 1,"max_query_terms": 12}}在这个示例中,查询将查找与给定文本相似的文档。21. 使用 ids 查询ids 查询用于根据文档 ID 匹配文档。示例:根据文档 ID 匹配文档{"query": {"ids": {"values": ["1", "2", "3"]}}在这个示例中,查询将匹配 ID 为 1、2 和 3 的文档。22. 使用 constant_score 查询constant_score 查询用于将查询的相关性评分设置为常量值。示例:将查询的相关性评分设置为常量值{"query": {"constant_score": {"filter": {"term": { "field1": "value1" }},"boost": 1.2}}}在这个示例中,查询将匹配 field1 为 value1 的文档,并将相关性评分设置为常量值 1.2。23. 使用 function_score 查询function_score 查询允许你根据特定函数调整文档的相关性评分。示例:根据特定函数调整相关性评分{"query": {"function_score": {"query": {"match": { "field1": "value1" }},"functions": [{"filter": { "match": { "field2": "value2" } },"weight": 2},{"filter": { "range": { "field3": { "gte": 10 } } },"weight": 1.5}],"boost_mode": "multiply"}}在这个示例中,查询将首先匹配 field1 为 value1 的文档,然后根据 field2 和 field3 的条件调整相关性评分。24. 使用 dis_max 查询dis_max 查询用于组合多个查询,并返回得分最高的文档。示例:组合多个查询并返回得分最高的文档{"query": {"dis_max": {"queries": [{ "match": { "field1": "value1" } },{ "match": { "field2": "value2" } }],"tie_breaker": 0.7}}}11在这个示例中,查询将组合 field1 和 field2 的匹配条件,并返回得分最高的文档。25. 使用 boosting 查询boosting 查询用于提升某些查询的得分,同时降低其他查询的得分。示例:提升和降低特定查询的得分{"query": {"boosting": {"positive": {"match": { "field1": "value1" }},"negative": {"match": { "field2": "value2" }},"negative_boost": 0.2}}}在这个示例中,查询将提升 field1 为 value1 的文档的得分,同时降低 field2 为 value2 的文档的得分。26. 使用 script_score 查询script_score 查询允许你使用脚本计算文档的相关性评分。示例:使用脚本计算相关性评分{"query": {"script_score": {"query": {"match": { "field1": "value1" }},"script": {"source": "doc['field2'].value * params.factor","params": {"factor": 1.5}}}}}在这个示例中,查询将首先匹配 field1 为 value1 的文档,然后使用脚本计算相关性评分。27. 使用 highlight 查询highlight 查询用于在查询结果中高亮显示匹配的部分。示例:高亮显示匹配的部分{"query": {"match": { "field1": "value1" }},"highlight": {"fields": {"field1": {}}}}在这个示例中,查询将匹配 field1 为 value1 的文档,并在结果中高亮显示匹配的部分。28. 使用 rescore 查询rescore 查询用于对初始查询结果进行重新评分。示例:对初始查询结果进行重新评分{"query": {"match": { "field1": "value1" }},"rescore": {"window_size": 50,"query": {"rescore_query": {"match_phrase": { "field1": "value1" }},"query_weight": 0.7,"rescore_query_weight": 1.2}}}15在这个示例中,查询将首先匹配 field1 为 value1 的文档,然后在前 50 个结果中使用 match_phrase 查询进行重新评分。29. 使用 percolate 查询percolate 查询用于查找与特定文档匹配的查询。示例:查找与特定文档匹配的查询{"query": {"percolate": {"field": "query","document": {"field1": "value1"}}}}10在这个示例中,查询将查找与文档 {"field1": "value1"} 匹配的查询。30. 使用 parent_id 查询parent_id 查询用于查找具有特定父文档 ID 的子文档。示例:查找具有特定父文档 ID 的子文档{"query": {"parent_id": {"type": "child_type","id": "parent_id_value"}}}8在这个示例中,查询将查找父文档 ID 为 parent_id_value 的子文档。31. 使用 has_child 查询has_child 查询用于查找具有特定子文档的父文档。示例:查找具有特定子文档的父文档{"query": {"has_child": {"type": "child_type","query": {"match": { "field1": "value1" }}}}}在这个示例中,查询将查找具有 field1 为 value1 的子文档的父文档。32. 使用 has_parent 查询has_parent 查询用于查找具有特定父文档的子文档。示例:查找具有特定父文档的子文档{"query": {"has_parent": {"parent_type": "parent_type","query": {"match": { "field1": "value1" }}}}}在这个示例中,查询将查找具有 field1 为 value1 的父文档的子文档。33. 使用 terms_set 查询terms_set 查询用于匹配字段值与查询中的多个值集合的交集。示例:匹配字段值与查询中的多个值集合的交集{"query": {"terms_set": {"field1": {"terms": ["value1", "value2", "value3"],"minimum_should_match_field": "required_matches"}}}}在这个示例中,查询将匹配 field1 的值与 ["value1", "value2", "value3"] 集合的交集,并且交集的大小由 required_matches 字段指定。34. 使用 intervals 查询intervals 查询用于基于间隔匹配文本。示例:基于间隔匹配文本{"query": {"intervals": {"field1": {"all_of": {"intervals": [{ "match": { "query": "value1" } },{ "match": { "query": "value2" } }],"max_gaps": 5,"ordered": true}}}}在这个示例中,查询将匹配 field1 中包含 value1 和 value2,并且它们之间的最大间隔为 5 且顺序一致的文档。35. 使用 rank_feature 查询rank_feature 查询用于基于特征字段的值对文档进行排名。示例:基于特征字段的值对文档进行排名{"query": {"rank_feature": {"field": "feature_field","boost": 1.5}}在这个示例中,查询将基于 feature_field 的值对文档进行排名,并应用一个 1.5 的提升因子。36. 使用 distance_feature 查询distance_feature 查询用于基于距离对文档进行排名。示例:基于距离对文档进行排名{"query": {"distance_feature": {"field": "date_field","pivot": "7d","origin": "now"}}}在这个示例中,查询将基于 date_field 的值与当前时间的距离对文档进行排名,使用 7d 作为基准距离。37. 使用 script 查询script 查询允许你使用脚本来定义自定义查询逻辑。示例:使用脚本定义自定义查询逻辑{"query": {"script": {"script": {"source": "doc['field1'].value > params.threshold","params": {"threshold": 10}}}}}在这个示例中,查询将匹配 field1 的值大于 10 的文档。38. 使用 wrapper 查询wrapper 查询用于包装一个 Base64 编码的查询。示例:包装一个 Base64 编码的查询{"query": {"wrapper": {"query": "eyJ0ZXJtIjp7ImZpZWxkMSI6InZhbHVlMSJ9fQ=="}}}在这个示例中,查询将解码 Base64 编码的查询 eyJ0ZXJtIjp7ImZpZWxkMSI6InZhbHVlMSJ9fQ== 并执行它。39. 使用 exists 查询exists 查询用于匹配包含特定字段的文档。示例:匹配包含特定字段的文档{"query": {"exists": {"field": "field1"}}在这个示例中,查询将匹配包含 field1 字段的文档。40. 使用 type 查询type 查询用于匹配特定类型的文档。示例:匹配特定类型的文档{"query": {"type": {"value": "type1"}}}在这个示例中,查询将匹配类型为 type1 的文档。41. 使用 terms 查询terms 查询用于匹配字段值在给定集合中的文档。示例:匹配字段值在给定集合中的文档{"query": {"terms": {"field1": ["value1", "value2", "value3"]}}}在这个示例中,查询将匹配 field1 的值在 ["value1", "value2", "value3"] 集合中的文档。42. 使用 wildcard 查询wildcard 查询用于匹配包含通配符的字段值。示例:匹配包含通配符的字段值{"query": {"wildcard": {"field1": "val*"}}}在这个示例中,查询将匹配 field1 的值以 val 开头的文档。43. 使用 regexp 查询regexp 查询用于匹配符合正则表达式的字段值。示例:匹配符合正则表达式的字段值{"query": {"regexp": {"field1": "val.*"}}}在这个示例中,查询将匹配 field1 的值符合正则表达式 val.* 的文档。44. 使用 prefix 查询prefix 查询用于匹配匹配以特定前缀开头的字段值。示例:匹配以特定前缀开头的字段值{"query": {"prefix": {"field1": "val"}}}在这个示例中,查询将匹配 field1 的值以 val 开头的文档。45. 使用 fuzzy 查询fuzzy 查询用于匹配与给定值相似的字段值,允许一定程度的模糊匹配。示例:匹配与给定值相似的字段值{"query": {"fuzzy": {"field1": {"value": "value1","fuzziness": "AUTO"}}}}12345678910在这个示例中,查询将匹配 field1 的值与 value1 相似的文档,模糊度设置为 AUTO。46. 使用 ids 查询ids 查询用于匹配特定 ID 的文档。示例:匹配特定 ID 的文档{"query": {"ids": {"values": ["1", "2", "3"]}}}1234567在这个示例中,查询将匹配 ID 为 1、2 或 3 的文档。47. 使用 geo_shape 查询geo_shape 查询用于匹配地理形状字段。示例:匹配地理形状字段{"query": {"geo_shape": {"location": {"shape": {"type": "envelope","coordinates": [[13.0, 53.0], [14.0, 52.0]]},"relation": "within"}}}}在这个示例中,查询将匹配 location 字段在指定的地理形状内的文档。48. 使用 geo_bounding_box 查询geo_bounding_box 查询用于匹配在指定地理边界框内的文档。示例:匹配在指定地理边界框内的文档{"query": {"geo_bounding_box": {"location": {"top_left": {"lat": 53.0,"lon": 13.0},"bottom_right": {"lat": 52.0,"lon": 14.0}}}}}在这个示例中,查询将匹配 location 字段在指定地理边界框内的文档。49. 使用 geo_distance 查询geo_distance 查询用于匹配在指定距离内的文档。示例:匹配在指定距离内的文档{"query": {"geo_distance": {"distance": "200km","location": {"lat": 52.0,"lon": 13.0}}}}在这个示例中,查询将匹配 location 字段在距离 52.0, 13.0 200 公里范围内的文档。50. 使用 geo_polygon 查询geo_polygon 查询用于匹配在指定地理多边形内的文档。示例:匹配在指定地理多边形内的文档{"query": {"geo_polygon": {"location": {"points": [{ "lat": 52.0, "lon": 13.0 },{ "lat": 53.0, "lon": 14.0 },{ "lat": 52.5, "lon": 13.5 }]}}}}在这个示例中,查询将匹配 location 字段在指定地理多边形内的文档。————————————————版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/weixin_46356409/article/details/141721001
  • 详解Redis的Zset类型及相关命令-转载
    Zset简介有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,着使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个分数。  ZADD添加或者更新指定的元素以及关联的分数到 zset 中,分数应该符合 double 类型,+inf/-inf 作为正负极限也是合法的。语法ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]ZADD 的相关选项:• XX:仅仅⽤于更新已经存在的元素,不会添加新元素。• NX:仅⽤于添加新元素,不会更新已经存在的元素。• CH:默认情况下,ZADD 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。• INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。时间复杂度:O(log(N))返回值:本次添加成功的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 1 "uno"(integer) 1redis> ZADD myzset 2 "two" 3 "three"(integer) 2redis> ZRANGE myzset 0 -1 WITHSCORES1) "one"2) "1"3) "uno"4) "1"5) "two"6) "2"7) "three"8) "3"ZCARD获取⼀个 zset 的基数(cardinality),即 zset 中的元素个数。语法ZCARD key时间复杂度:O(1)返回值:zset 内的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZCARD myzset(integer) 2ZCOUNT返回分数在 min 和 max 之间的元素个数,默认情况下,min 和 max 都是包含的,可以通过 ( 排除。语法ZCOUNT key min max时间复杂度:O(log(N))返回值:满⾜条件的元素列表个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZCOUNT myzset -inf +inf(integer) 3redis> ZCOUNT myzset (1 3(integer) 2ZRANGE返回指定区间⾥的元素,分数按照升序。带上 WITHSCORES 可以把分数也返回。语法ZRANGE key start stop [WITHSCORES]时间复杂度:O(log(N)+M)返回值:区间内的元素列表。举例redis> ZADD myzset 1 "one" 2 "two" 3 "three"(integer) 3redis> ZRANGE myzset 0 -11) "one"2) "two"3) "three"redis> ZRANGE myzset 2 31) "three"redis> ZRANGE myzset -2 -11) "two"2) "three"ZREVRANGE返回指定区间⾥的元素,分数按照降序。带上 WITHSCORES 可以把分数也返回。语法ZREVRANGE key start stop [WITHSCORES]时间复杂度:O(log(N)+M)返回值:区间内的元素列表。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZREVRANGE myzset 0 -11) "three"2) "two"3) "one"redis> ZREVRANGE myzset 2 31) "one"redis> ZREVRANGE myzset -2 -11) "two"2) "one"ZRANGEBYSCORE返回分数在 min 和 max 之间的元素,默认情况下,min 和 max 都是包含的,可以通过 ( 排除。语法ZRANGEBYSCORE key min max [WITHSCORES]时间复杂度:O(log(N)+M)返回值:区间内的元素列表。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZRANGEBYSCORE myzset -inf +inf1) "one"2) "two"3) "three"redis> ZRANGEBYSCORE myzset 1 21) "one"2) "two"redis> ZRANGEBYSCORE myzset (1 21) "two"redis> ZRANGEBYSCORE myzset (1 (2(empty array)ZPOPMAX删除并返回分数最⾼的 count 个元素。语法ZPOPMAX key [count]时间复杂度:O(log(N) * M)返回值:分数和元素列表。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZPOPMAX myzset1) "three"2) "3"BZPOPMAXZPOPMAX 的阻塞版本。语法BZPOPMAX key [key ...] timeout时间复杂度:O(log(N))返回值:元素列表。举例redis> DEL zset1 zset2(integer) 0redis> ZADD zset1 0 a 1 b 2 c(integer) 3redis> BZPOPMAX zset1 zset2 01) "zset1"2) "c"3) "2"ZPOPMIN删除并返回分数最低的 count 个元素。语法ZPOPMIN key [count]时间复杂度:O(log(N) * M)返回值:分数和元素列表。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZPOPMIN myzset1) "one"2) "1"BZPOPMINZPOPMIN 的阻塞版本。语法BZPOPMIN key [key ...] timeout时间复杂度:O(log(N))返回值:元素列表。举例redis> DEL zset1 zset2(integer) 0redis> ZADD zset1 0 a 1 b 2 c(integer) 3redis> BZPOPMIN zset1 zset2 01) "zset1"2) "a"3) "0"ZRANK返回指定元素的排名,升序。语法ZRANK key member时间复杂度:O(log(N))返回值:排名。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZRANK myzset "three"(integer) 2redis> ZRANK myzset "four"(nil)redis> ZRANK myzset "three" WITHSCORE1) (integer) 22) "3"redis> ZRANK myzset "four" WITHSCORE(nil)ZREVRANK返回指定元素的排名,降序。语法ZREVRANK key member时间复杂度:O(log(N))返回值:排名。redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZREVRANK myzset "one"(integer) 2redis> ZREVRANK myzset "four"(nil)redis> ZREVRANK myzset "three" WITHSCORE1) (integer) 02) "3"redis> ZREVRANK myzset "four" WITHSCORE(nil)ZSCORE返回指定元素的分数。语法ZSCORE key member时间复杂度:O(1)返回值:分数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZSCORE myzset "one""1"ZREM删除指定的元素。语法ZREM key member [member ...]时间复杂度:O(M*log(N))返回值:本次操作删除的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZREM myzset "two"(integer) 1redis> ZRANGE myzset 0 -1 WITHSCORES1) "one"2) "1"3) "three"4) "3"ZREMRANGEBYRANK按照排序,升序删除指定范围的元素,左闭右闭。语法ZREMRANGEBYRANK key start stop时间复杂度:O(log(N)+M)返回值:本次操作删除的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZREMRANGEBYRANK myzset 0 1(integer) 2redis> ZRANGE myzset 0 -1 WITHSCORES1) "three"2) "3"ZREMRANGEBYSCORE按照分数删除指定范围的元素,左闭右闭。语法ZREMRANGEBYSCORE key min max时间复杂度:O(log(N)+M)返回值:本次操作删除的元素个数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZADD myzset 3 "three"(integer) 1redis> ZREMRANGEBYSCORE myzset -inf (2(integer) 1redis> ZRANGE myzset 0 -1 WITHSCORES1) "two"2) "2"3) "three"4) "3"ZINCRBY为指定的元素的关联分数添加指定的分数值。语法ZINCRBY key increment member时间复杂度:O(log(N))返回值:增加后元素的分数。举例redis> ZADD myzset 1 "one"(integer) 1redis> ZADD myzset 2 "two"(integer) 1redis> ZINCRBY myzset 2 "one""3"redis> ZRANGE myzset 0 -1 WITHSCORES1) "two"2) "2"3) "one"4) "3"ZINTERSTORE求出给定有序集合中元素的交集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。语法ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]时间复杂度:O(N*K)+O(M*log(M)) N 是输⼊的有序集合中, 最⼩的有序集合的元素个数; K 是输⼊了⼏个有序集合; M 是最终结果的有序集合的元素个数.返回值:⽬标集合中的元素个数。举例redis> ZADD zset1 1 "one"(integer) 1redis> ZADD zset1 2 "two"(integer) 1redis> ZADD zset2 1 "one"(integer) 1redis> ZADD zset2 2 "two"(integer) 1redis> ZADD zset2 3 "three"(integer) 1redis> ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3(integer) 2redis> ZRANGE out 0 -1 WITHSCORES1) "one"2) "5"3) "two"4) "10"ZUNIONSTORE求出给定有序集合中元素的并集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。语法ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]时间复杂度:O(N)+O(M*log(M)) N 是输⼊的有序集合总的元素个数; M 是最终结果的有序集合的元素个数.返回值:⽬标集合中的元素个数。举例redis> ZADD zset1 1 "one"(integer) 1redis> ZADD zset1 2 "two"(integer) 1redis> ZADD zset2 1 "one"(integer) 1redis> ZADD zset2 2 "two"(integer) 1redis> ZADD zset2 3 "three"(integer) 1redis> ZUNIONSTORE out 2 zset1 zset2 WEIGHTS 2 3(integer) 3redis> ZRANGE out 0 -1 WITHSCORES1) "one"2) "5"3) "three"4) "9"5) "two"6) "10"内部编码有序集合类型的内部编码有两种:• ziplist(压缩列表):当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个),同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作为有序集合的内部实现,ziplist 可以有效减少内存的使⽤。• skiplist(跳表):当 ziplist 条件不满⾜时,有序集合会使⽤ skiplist 作为内部实现,因为此时ziplist 的操作效率会下降。1)当元素个数较少且每个元素较⼩时,内部编码为 ziplist:127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3(integer) 3127.0.0.1:6379> object encoding zsetkey"ziplist"2)当元素个数超过 128 个,内部编码 skiplist:127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3 ... 省略 ... 82 e129(integer) 129127.0.0.1:6379> object encoding zsetkey"skiplist"3)当某个元素⼤于 64 字节时,内部编码 skiplist:127.0.0.1:6379> zadd zsetkey 50 "one string bigger than 64 bytes ... 省略 ..."(integer) 1127.0.0.1:6379> object encoding zsetkey"skiplist”应用场景1.排行榜Zset非常适合用于实现各种排行榜,如游戏内的玩家排名、社交平台的热门帖子排名等。元素可以是玩家的ID或帖子的ID,分数可以是玩家的积分或帖子的点赞数、评论数等。可以使用ZRANGE或ZREVRANGE命令来获取排名前列的元素,或使用ZRANK或ZREVRANK命令来获取特定元素的排名。2.延时队列Zset可以用于实现延时队列,其中元素代表任务,分数代表任务的执行时间戳。通过定期检查Zset中分数最小的元素(即最早应该执行的任务),可以实现任务的定时执行。当任务执行后,可以从Zset中删除该元素。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/wmh_1234567/article/details/144493484
  • [技术干货] 详解Redis的Hash类型及相关命令-转载
    HSET设置 hash 中指定的字段(field)的值(value)。语法HSET key field value [field value ...]时间复杂度:插⼊⼀组 field 为 O(1), 插⼊ N 组 field 为 O(N)返回值:添加的字段的个数。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HGET myhash field1"Hello"redis> HSET myhash field2 "Hi" field3 "World"(integer) 2redis> HGET myhash field2"Hi"redis> HGET myhash field3"World"redis> HGETALL myhash1) "field1"2) "Hello"3) "field2"4) "Hi"5) "field3"6) "World"HGET获取 hash 中指定字段的值。语法HGET key field时间复杂度:O(1)返回值:字段对应的值或者 nil。举例redis> HSET myhash field1 "foo"(integer) 1redis> HGET myhash field1"foo"redis> HGET myhash field2(nil)HEXISTS判断 hash 中是否有指定的字段。语法HEXISTS key field时间复杂度:O(1)返回值:1 表⽰存在,0 表⽰不存在。举例redis> HSET myhash field1 "foo"(integer) 1redis> HEXISTS myhash field1(integer) 1redis> HEXISTS myhash field2(integer) 0HDEL删除 hash 中指定的字段。语法HDEL key field [field ...]时间复杂度:删除⼀个元素为 O(1). 删除 N 个元素为 O(N).返回值:本次操作删除的字段个数。举例redis> HSET myhash field1 "foo"(integer) 1redis> HDEL myhash field1(integer) 1redis> HDEL myhash field2(integer) 0HKEYS获取 hash 中的所有字段。语法HKEYS key时间复杂度:O(N), N 为 field 的个数.返回值:字段列表。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HKEYS myhash1) "field1"2) "field2"HVALS获取 hash 中的所有的值。语法HVALS key时间复杂度:O(N), N 为 field 的个数.返回值:所有的值。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HVALS myhash1) "Hello"2) "World"HGETALL获取 hash 中的所有字段以及对应的值。语法HGETALL key时间复杂度:O(N), N 为 field 的个数.返回值:字段和对应的值。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HGETALL myhash1) "field1"2) "Hello"3) "field2"4) "World"HMGET⼀次获取 hash 中多个字段的值。语法HMGET key field [field ...]时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.返回值:字段对应的值或者 nil。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HMGET myhash field1 field2 nofield1) "Hello"2) "World"3) (nil)HLEN获取 hash 中的所有字段的个数。语法HLEN key时间复杂度:O(1)返回值:字段个数。举例redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HLEN myhash(integer) 2HSETNX在字段不存在的情况下,设置 hash 中的字段和值。语法HSETNX key field value时间复杂度:O(1)返回值:1 表⽰设置成功,0 表⽰失败。举例redis> HSETNX myhash field "Hello"(integer) 1redis> HSETNX myhash field "World"(integer) 0redis> HGET myhash field"Hello"HINCRBY将 hash 中字段对应的数值添加指定的值。语法HINCRBY key field increment时间复杂度:O(1)返回值:该字段变化之后的值。举例redis> HSET myhash field 5(integer) 1redis> HINCRBY myhash field 1(integer) 6redis> HINCRBY myhash field -1(integer) 5redis> HINCRBY myhash field -10(integer) -5HINCRBYFLOATHINCRBY 的浮点数版本。语法HINCRBYFLOAT key field increment时间复杂度:O(1)返回值:该字段变化之后的值。举例redis> HSET mykey field 10.50(integer) 1redis> HINCRBYFLOAT mykey field 0.1"10.6"redis> HINCRBYFLOAT mykey field -5"5.6"redis> HSET mykey field 5.0e3(integer) 0redis> HINCRBYFLOAT mykey field 2.0e2"5200"内部编码哈希的内部编码有两种:ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个)、同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐hashtable 更加优秀。hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)。下⾯的⽰例演⽰了哈希类型的内部编码,以及响应的变化。1)当 field 个数⽐较少且没有⼤的 value 时,内部编码为 ziplist:127.0.0.1:6379> hmset hashkey f1 v1 f2 v2OK127.0.0.1:6379> object encoding hashkey"ziplist”2)当有 value ⼤于 64 字节时,内部编码会转换为 hashtable:127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 bytes ... 省略 ..."OK127.0.0.1:6379> object encoding hashkey"hashtable"3)当 field 个数超过 512 时,内部编码也会转换为 hashtable:127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513OK127.0.0.1:6379> object encoding hashkey"hashtable"应用场景1.缓存数据类似于String类型,Hash类型也可以用于缓存数据。不过,由于Hash类型可以存储多个字段和字段值,因此更适合用于缓存具有多个属性的数据。例如,可以将经常访问的商品信息、用户信息等缓存在Hash类型中,以便快速读取和响应客户端请求。2.对象属性存储Hash类型非常适合存储对象的各个属性,如用户信息、商品信息等。可以将对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。例如,要存储ID为1的汽车对象,可以分别使用名为color、name和price的字段来存储该辆汽车的颜色、名称和价格。同样,对于用户信息,可以将用户的ID作为Hash类型的键,用户的各种属性(如用户名、年龄、性别等)作为字段和字段值进行存储。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/wmh_1234567/article/details/144487762
  • [技术干货] JedisPool和Jedis的生命周期
    JedisPool和Jedis是Java中用于与Redis进行交互的客户端库。以下是关于JedisPool和Jedis推荐的生命周期的详细解释:JedisPool的生命周期创建:JedisPool是一个连接池,用于管理多个Jedis连接。在创建JedisPool时,需要配置连接池的参数,如最大连接数、最大空闲连接数、最小空闲连接数等。JedisPool通常被设置为单例或静态的,以便在应用程序中共享。使用:当需要执行Redis操作时,从JedisPool中获取一个Jedis实例。使用Jedis实例执行Redis命令。操作完成后,将Jedis实例归还给JedisPool,以便其他线程或操作可以重用该连接。销毁:在应用程序关闭或不再需要JedisPool时,应关闭连接池以释放资源。这通常涉及调用JedisPool的close方法,该方法会关闭池中的所有连接并释放相关资源。Jedis的生命周期获取:Jedis实例不是线程安全的,因此每个线程在使用Jedis时都应从JedisPool中获取一个新的实例。通过调用JedisPool的getResource方法获取Jedis实例。使用:使用Jedis实例执行Redis命令,如set、get等。Jedis对象会维护自己的状态(如连接、事务等),因此应避免多个线程共享同一个Jedis实例。归还/销毁:操作完成后,应将Jedis实例归还给JedisPool,而不是直接关闭它。JedisPool会管理连接的回收和重用。如果在Jedis实例上调用close方法,并且该实例是从JedisPool中获取的,则实际上是将该实例归还给连接池,而不是关闭连接。最佳实践JedisPool配置:根据应用程序的需求合理配置JedisPool的参数,如最大连接数、最大空闲连接数等。确保JedisPool是单例或静态的,以便在应用程序中共享。Jedis使用:避免多个线程共享同一个Jedis实例。使用try-with-resources语句或确保在finally块中关闭Jedis实例(实际上是将其实例归还给JedisPool)。资源管理:定期监控JedisPool的性能和资源使用情况。在应用程序关闭时,确保关闭JedisPool以释放资源。综上所述,JedisPool和Jedis的生命周期管理对于确保Redis客户端的稳定性和性能至关重要。通过合理配置和使用这两个组件,可以优化Redis操作的效率和可靠性。
  • [技术干货] Redis中String 的底层结构
     String底层一共包含三种结构:int,embstr,raw存储value的时候包含两个结构,RedisObject和sdsint:Long类型的整数时,RedisObject的ptr指针直接赋值为整数数据,不在额外的指针再指向整数了,节省了指针的空间开销。Embstr:压缩字符串,是一个简单动态字符串结构,不是c语言中的char数组,是单独实现的sds,sds中包含len,alloc,flag,char[] buf len,是当前字符串的长度,alloc是分配内存的最大字节,flag:表示的sds的类型有sds6 sds8 buf中存储的就是数组。RedisObject 和sds是在一起相邻存储的。raw:也是sds结构,因为sds存储空间变大,和embstr的区别就是RedisObject和sds是分开存储的。为什么有了char数组,还要有len变量,是为了便于返回数组长度的时候,不用再遍历char数组到\0计算了,可以直接返回。​​
  • [技术干货] Redis集群
    Redis集群是Redis的分布式解决方案,旨在通过多个节点共同工作来提高Redis的稳定性和效率。以下是对Redis集群的详细介绍:一、定义与目的Redis集群通过添加服务器的数量提供相同的服务,从而让服务器达到一个稳定、高效的状态。它主要解决单个Redis实例存在的不稳定性、读写能力有限以及存储容量受限等问题。二、特性可扩展性:Redis集群最多可扩展到1000个节点上,这极大地提高了Redis数据库的可扩展性。可用性:Redis集群继续运行有两个条件,即大多数主节点必须可达,无法达到的主节点必须有一个备份从节点。这一特性有助于提高Redis数据库的可用性。写入安全性:Redis集群尝试以写入安全的方式运行,它将尽量保留与集群中多数主节点连接的任何客户端的写入。数据分片:Redis集群通过在数据库中分片数据来工作。分片是一种数据库分区方案,将数据库中不同的行(在Redis中是键值对)分布到多个节点上,以便每个节点包含一部分数据。这意味着如果一个节点宕机,只有一部分数据将不可用,这将允许许多数据库请求正常进行。主/从架构:Redis集群使用主从复制,以便集群中的每个主节点都有一个备份从节点。如果其中一个主节点失败,相应的从节点可以被指定为新的主节点,对整个集群的影响很小。三、工作原理Redis集群通过哈希槽(Hash Slot)机制实现数据分片存储。每个节点负责一部分哈希槽,当客户端请求数据时,Redis会根据数据的键计算哈希值,并确定该数据所属的哈希槽,然后将请求转发到负责该哈希槽的节点。四、搭建与配置搭建Redis集群需要准备多台服务器或虚拟机,并在每台服务器上安装Redis。然后,为每个节点创建一个独立的配置目录和配置文件,设置集群相关的参数,如cluster-enabled、cluster-config-file、cluster-node-timeout等。最后,使用redis-cli工具创建集群,并将节点之间的关系绑定起来。五、高可用性保障Redis集群的高可用性主要由以下几个方面保障:自动故障转移:当主节点发生故障时,集群会自动提升对应的从节点为新的主节点,保证服务持续可用。数据分片:通过哈希槽机制,数据分散存储在多个节点上,避免单点瓶颈。去中心化架构:Redis集群中没有单点故障,每个节点相互通讯,共同维护集群状态。六、应用场景Redis集群适用于需要高并发、高可用性和大数据存储的分布式系统。例如,热点数据的缓存、限时任务、计数器、分布式锁、排行榜、社交网站的基本功能(如点赞、踩、关注/被关注、共同好友等)以及队列操作等场景都可以使用Redis集群来实现。综上所述,Redis集群是一种高效、可扩展且高可用的分布式数据库解决方案。它通过数据分片、主/从架构和自动故障转移等机制,提供了稳定、可靠的数据存储和服务。
  • [技术干货] Redis 分布式锁详解
    当然,Redis 分布式锁是一种常用的解决分布式系统中资源同步访问的方法。以下是一篇关于 Redis 分布式锁的详细指南,包括原理、实现以及注意事项。Redis 分布式锁详解一、引言在分布式系统中,多个进程或线程可能会同时访问和修改共享资源,这会导致数据不一致的问题。为了解决这一问题,分布式锁应运而生。Redis 分布式锁因其高性能和易用性,成为了一种广泛使用的解决方案。二、Redis 分布式锁的原理Redis 分布式锁的实现通常依赖于 Redis 的单线程模型和原子操作。常见的实现方式包括使用 SETNX 命令、SET 命令的 NX 和 EX 选项,以及基于 Lua 脚本的原子操作。2.1 SETNX 命令SETNX 是 Redis 中的一个命令,全称是 “SET if Not eXists”。它用于设置一个键值对,当且仅当该键不存在时才会成功设置,并返回 1;如果键已经存在,则设置失败,返回 0。利用这一特性,我们可以实现一个简单的分布式锁。2.2 SET 命令的 NX 和 EX 选项Redis 2.6.12 版本及以后,SET 命令增加了 NX 和 EX 选项。NX 表示仅在键不存在时设置键,EX 表示设置键的过期时间。通过这两个选项,我们可以一次性完成锁的获取和过期时间的设置,从而简化了分布式锁的实现。2.3 Lua 脚本为了确保分布式锁的原子性,可以使用 Lua 脚本来实现复杂的操作。Lua 脚本在 Redis 中是以原子方式执行的,这保证了脚本中的多个命令在执行过程中不会被其他命令打断。三、Redis 分布式锁的实现以下是一个基于 Redis SET 命令的 NX 和 EX 选项实现的分布式锁示例:3.1 锁获取import redis import uuid import time # 连接到 Redis 服务器 client = redis.StrictRedis(host='localhost', port=6379, db=0) def acquire_lock(lock_name, acquire_timeout=10, lock_timeout=10): identifier = str(uuid.uuid4()) end = time.time() + acquire_timeout while time.time() < end: if client.set(lock_name, identifier, nx=True, px=lock_timeout * 1000): return identifier time.sleep(0.001) return False 在这个示例中,acquire_lock 函数尝试获取一个名为 lock_name 的锁。它生成一个唯一的标识符 identifier,并使用 SET 命令的 NX 和 PX 选项尝试设置锁。如果设置成功,则返回标识符;否则,循环等待直到超时。3.2 锁释放def release_lock(lock_name, identifier): pipe = client.pipeline(True) while True: try: pipe.watch(lock_name) if pipe.get(lock_name) == identifier: pipe.multi() pipe.delete(lock_name) pipe.execute() return True pipe.unwatch() break except redis.exceptions.WatchError: continue return False 在 release_lock 函数中,我们使用 Redis 的事务机制来确保锁的正确释放。通过 WATCH 命令监视锁键,如果锁键的值与我们的标识符匹配,则使用 MULTI 和 EXEC 命令删除锁键。如果在事务执行过程中锁键被其他进程修改,则会引发 WatchError 异常,此时我们重新尝试释放锁。四、注意事项锁过期时间:设置合理的锁过期时间非常重要。如果过期时间太短,可能会导致锁被意外释放;如果过期时间太长,则可能导致资源被长时间占用。续期机制:对于需要长时间持有的锁,可以考虑实现续期机制,即在锁即将过期时重新设置过期时间。这需要在业务逻辑中增加相应的处理。可重入性:上述示例中的锁实现是不可重入的。如果需要可重入锁,可以在锁值中记录获取锁的次数,并在释放锁时根据次数递减。锁释放失败:由于网络或其他原因,锁可能无法被正确释放。为了避免这种情况,可以使用额外的机制(如日志记录、监控等)来检测和清理未释放的锁。Redis 实例的高可用性:如果 Redis 实例发生故障,可能会导致分布式锁失效。因此,在生产环境中,通常需要使用 Redis 集群或主从复制来提高 Redis 的可用性。五、总结Redis 分布式锁是一种高效且易用的解决方案,适用于大多数分布式系统中的资源同步访问场景。通过合理设置锁过期时间、实现续期机制以及注意锁的释放和可重入性等问题,可以确保分布式锁的正确性和可靠性。希望这篇指南对你理解和实现 Redis 分布式锁有所帮助。如果你有任何问题或需要进一步的帮助,请随时提问。
  • [专题汇总] 快来看看吧,总有一篇帖子可以帮到你,11月干货合集。
     大家好一年马上结束了给大家带来11月份的干货合集,本次涉及springboot,springmvc,Python,MySQL,Redis,HarmonyOS等多类知识,希望可以帮助到大家。 1.使用SQL实现按每小时统计数据【转】 https://bbs.huaweicloud.com/forum/thread-0296168347647671062-1-1.html  2.MySQL获取数据库内所有表格数据总数的示例代码【转】 https://bbs.huaweicloud.com/forum/thread-02109168347516352050-1-1.html  3.Redis主从复制的实现示例【转】 https://bbs.huaweicloud.com/forum/thread-0296168346418210061-1-1.html  4.MySQL启动方式之systemctl与mysqld的对比详解【转】 https://bbs.huaweicloud.com/forum/thread-0296168346377082060-1-1.html  5.全面解析MySQL常见问题的排查与解决方法【转】 https://bbs.huaweicloud.com/forum/thread-0276168346339971051-1-1.html  6.Python代码调试Debug的实用技巧分享【转】 https://bbs.huaweicloud.com/forum/thread-0241168345445980044-1-1.html  7.Bash脚本实现实时监测登录【转】 https://bbs.huaweicloud.com/forum/thread-0241168345292684043-1-1.html  8.使用Python删除Word中表格的方法【转】 https://bbs.huaweicloud.com/forum/thread-02109168344979927049-1-1.html  9.基于Go语言实现压缩文件处理【转】 https://bbs.huaweicloud.com/forum/thread-0276168344745791050-1-1.html  10.Python实现批量图片去重【转】 https://bbs.huaweicloud.com/forum/thread-02112168344680315056-1-1.html  11.python实现二维列表的列表生成式【转】 https://bbs.huaweicloud.com/forum/thread-0296168340813812059-1-1.html  12.基于Python实现IP代理池【转】 https://bbs.huaweicloud.com/forum/thread-0276168340692413049-1-1.html  13.Gin框架中异步任务的实现【转】 https://bbs.huaweicloud.com/forum/thread-0296168340516828058-1-1.html  14.使用Go语言中的Context取消协程执行的操作代码【转】 https://bbs.huaweicloud.com/forum/thread-02109168340403402048-1-1.html  15.使用Python实现获取Apollo配置【转】 https://bbs.huaweicloud.com/forum/thread-02112168340011491055-1-1.html  16.【HarmonyOS】抖动动画方案 https://bbs.huaweicloud.com/forum/thread-02119168246419995040-1-1.html  17.【HarmonyOS】九宫格拼图游戏 https://bbs.huaweicloud.com/forum/thread-02112168246323162046-1-1.html  18.【HarmonyOS】Web组件同步与异步数据获取 https://bbs.huaweicloud.com/forum/thread-02109168246260516045-1-1.html  19.【HarmonyOS】图片下载加载方案 https://bbs.huaweicloud.com/forum/thread-02112168246161439045-1-1.html  20.【HarmonyOS】动画旋转方式比较 https://bbs.huaweicloud.com/forum/thread-0241168246072330040-1-1.html  21.Linux下的基本指令-转载 https://bbs.huaweicloud.com/forum/thread-02108167416586006015-1-1.html  22.Linux:认识文件系统-转载 https://bbs.huaweicloud.com/forum/thread-02115167416457957013-1-1.html  23.【JAVA】Spring MVC 详解-转载 https://bbs.huaweicloud.com/forum/thread-02108167416063721014-1-1.html  24.【Spring】MVC-转载 https://bbs.huaweicloud.com/forum/thread-0229167415942031022-1-1.html  25.【Spring篇】Spring中的Bean管理-转载 https://bbs.huaweicloud.com/forum/thread-02115167415823291012-1-1.html 
  • [技术干货] Redis主从复制的实现示例【转】
    Redis 主从复制主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。首次同步(全量复制)发送SYNC命令:当从节点(Slave)决定成为某个主节点(Master)的从节点时,它会向主节点发送一个 SYNC 命令。BGSAVE生成RDB快照:主节点接收到 SYNC 命令后,会执行 BGSAVE 命令。BGSAVE 命令会在后台生成一个 RDB 快照文件,同时主节点继续处理其他命令。在生成 RDB 快照的过程中,主节点会将所有新的写操作记录到一个缓冲区中。快照文件传输:一旦 RDB 快照文件生成完毕,主节点会将这个快照文件发送给从节点。在发送快照文件的过程中,主节点会继续接收并处理新的命令,这些命令会被记录到缓冲区中。加载快照文件:从节点接收到 RDB 快照文件后,会加载这个文件,将其内容应用到自己的数据集中。追赶复制:加载完快照文件后,从节点会向主节点发送一个 PSYNC 命令,请求获取主节点缓冲区中未发送的写操作。主节点收到 PSYNC 命令后,会将缓冲区中的写操作发送给从节点。增量复制命令传播:在完成首次同步后,从节点会进入命令传播阶段。在这个阶段,主节点会将其接收到的所有写操作(例如,SET、DEL等)实时地发送给从节点。从节点会执行这些写操作,以保持与主节点的数据一致性。心跳检测:在命令传播阶段,主从节点之间会定期发送心跳包(通常是PING和PONG命令)来检测连接状态。如果从节点在一定时间内没有收到主节点的心跳包或命令,它会认为连接已经断开,并尝试重新与主节点建立连接。重新同步:如果从节点与主节点之间的连接断开,或者从节点的数据与主节点不一致(例如,由于网络分区或磁盘故障),从节点会尝试重新与主节点进行同步。在重新同步的过程中,从节点会发送一个 PSYNC 命令给主节点,请求获取最新的数据。主节点会根据从节点提供的复制偏移量(replication offset)来决定是进行全量复制还是部分复制(增量复制)。注意复制偏移量:主从节点在复制过程中会维护一个复制偏移量,用于记录已经复制的数据位置。复制偏移量有助于从节点在重新同步时确定需要从主节点获取哪些数据。从节点只读:默认情况下,从节点是只读的。这意味着你不能在从节点上执行写操作(例如,SET命令)。如果需要在从节点上执行写操作,可以将其配置为可写模式(但通常不推荐这样做,因为这可能会破坏数据一致性)。延迟问题:由于网络延迟和命令传播时间的影响,从节点的数据可能会比主节点稍微落后一些。在某些情况下(例如,写操作非常频繁时),这种延迟可能会变得比较明显。故障切换:当主节点出现故障时,需要手动或自动地将一个从节点提升为主节点(例如,使用哨兵或集群机制)。在提升从节点为主节点之前,需要确保该从节点的数据与主节点一致(或者尽可能一致)。搭建Redis主从复制环境准备:Master节点:192.168.80.10Slave1节点:192.168.80.11Slave2节点:192.168.80.12安装Redis环境准备:1234systemctl stop firewalldsystemctl disable firewalldsetenforce 0sed -i 's/enforcing/disabled/' /etc/selinux/config修改内核参数:12345vim /etc/sysctl.conf# 添加以下内容vm.overcommit_memory = 1net.core.somaxconn = 2048sysctl -p安装Redis:12345yum install -y gcc gcc-c++ maketar zxvf /opt/redis-7.0.9.tar.gz -C /opt/cd /opt/redis-7.0.9makemake PREFIX=/usr/local/redis install创建Redis工作目录并设置用户:1234mkdir /usr/local/redis/{conf,log,data}cp /opt/redis-7.0.9/redis.conf /usr/local/redis/conf/useradd -M -s /sbin/nologin redischown -R redis.redis /usr/local/redis/设置环境变量:1234vim /etc/profile# 添加以下内容PATH=$PATH:/usr/local/redis/binsource /etc/profile定义systemd服务管理脚本:12345678910111213141516171819vim /usr/lib/systemd/system/redis-server.service# 添加以下内容[Unit]Description=Redis ServerAfter=network.target[Service]User=redisGroup=redisType=forkingTimeoutSec=0PIDFile=/usr/local/redis/log/redis_6379.pidExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.confExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s QUIT $MAINPIDPrivateTmp=true[Install]WantedBy=multi-user.target修改Redis配置文件Master节点配置:12345678910111213vim /usr/local/redis/conf/redis.conf# 修改以下内容bind 0.0.0.0protected-mode noport 6379daemonize yespidfile /usr/local/redis/log/redis_6379.pidlogfile "/usr/local/redis/log/redis_6379.log"dir /usr/local/redis/dataappendonly yes# requirepass abc123 # 可选,设置redis密码systemctl restart redis-server.serviceSlave节点配置:1234567891011121314vim /usr/local/redis/conf/redis.conf# 修改以下内容bind 0.0.0.0protected-mode noport 6379daemonize yespidfile /usr/local/redis/log/redis_6379.pidlogfile "/usr/local/redis/log/redis_6379.log"dir /usr/local/redis/dataappendonly yesreplicaof 192.168.80.10 6379# masterauth abc123 # 可选,设置Master节点的密码,仅在Master节点设置了requirepasssystemctl restart redis-server.service验证主从效果在Master节点上看日志:123456tail -f /usr/local/redis/log/redis_6379.log # 应显示类似以下内容Replica 192.168.80.11:6379 asks for synchronizationReplica 192.168.80.12:6379 asks for synchronizationSynchronization with replica 192.168.80.11:6379 succeededSynchronization with replica 192.168.80.12:6379 succeeded在Master节点上验证从节点:1234567redis-cli info replication# 应显示类似以下内容# Replicationrole:masterconnected_slaves:2slave0:ip=192.168.80.11,port=6379,state=online,offset=1246,lag=0slave1:ip=192.168.80.12,port=6379,state=online,offset=1246,lag=1
  • [问题求助] docker中使用华为redis客户端sasl创建客户端耗时非常长
    用到了华为redis客户端,版本是jedisclient-3.6.3-h0.cbu.mrs.330.r9.jar创建客户端实例JedisCluster,本地和服务器上链接正常,使用docker创建镜像后,只有少数情况下正常,多数情况下都需要16秒才能创建,跟踪代码定位发现在JdisAuth.java中createSaslClient里调用Sasl.createSaslClient需要16秒,jdk换成和服务器正常使用的jdk一样也不行,怀疑可能是网络问题,各位有没有遇到相似问题的,麻烦提供一下指点,非常感谢
  • [专题汇总] 你想知道的这里都有,10月份干货合集,速进
     大家好,四季度的第一个干货合集来了,这次带来的东西主要涉及到golang,python,MySQL,redis,PostgreSQL,docker,minio,鸿蒙等等,希望可以帮助到到家 1. golang gin ShouldBind的介绍和使用示例详解【转载】 https://bbs.huaweicloud.com/forum/thread-02127165743740541019-1-1.html  2.golang flag介绍和使用示例【转载】 https://bbs.huaweicloud.com/forum/thread-0205165743832841012-1-1.html  3.Go语言中的格式化输出占位符的用法详解【转】 https://bbs.huaweicloud.com/forum/thread-0242165743874465013-1-1.html  4.Python中格式化字符串的方法总结【转载】 https://bbs.huaweicloud.com/forum/thread-02107165744051753023-1-1.html  5.Python使用进程池并发执行SQL语句的操作代码【转载】 https://bbs.huaweicloud.com/forum/thread-02111165744119162009-1-1.html  6.Mysql转PostgreSQL注意事项及说明【转】 https://bbs.huaweicloud.com/forum/thread-0205165745689855016-1-1.html  7.一文彻底讲清该如何处理mysql的死锁问题【转载】 https://bbs.huaweicloud.com/forum/thread-02111165745597896010-1-1.html  8.Redis实现分布式事务的示例【转载】 https://bbs.huaweicloud.com/forum/thread-0242165745553696016-1-1.html  9.MySQL服务无法启动且服务没有报告任何错误解决办法【转载】 https://bbs.huaweicloud.com/forum/thread-02127165745354539021-1-1.html      10.Python+OpenCV实现火焰检测【转载】 https://bbs.huaweicloud.com/forum/thread-0205165744941700014-1-1.html  11.Python Word实现批量替换文本并生成副本【转载】 https://bbs.huaweicloud.com/forum/thread-02127165744886949020-1-1.html  12.Python实现OFD文件转PDF【转载】 https://bbs.huaweicloud.com/forum/thread-0286165744755315017-1-1.html  13.Python中将文件从一个服务器复制到另一个服务器的4种方法【转】 https://bbs.huaweicloud.com/forum/thread-0242165744680560015-1-1.html  14.Python实现将pdf文档保存成图片格式【转载】 https://bbs.huaweicloud.com/forum/thread-0242165744483484014-1-1.html  15.Python通过keyboard库实现模拟和监听键盘【转载】 https://bbs.huaweicloud.com/forum/thread-0205165744195219013-1-1.html  16.docker 配置国内镜像源 https://bbs.huaweicloud.com/forum/thread-0286165634815059009-1-1.html  17.Typora 代码块Mac风格化 https://bbs.huaweicloud.com/forum/thread-02111165634917052004-1-1.html  18.MinIO上传和下载文件及文件完整性校验 https://bbs.huaweicloud.com/forum/thread-0286165634713872008-1-1.html  19.鸿蒙系统特性 https://bbs.huaweicloud.com/forum/thread-02127165634384647014-1-1.html  20.Java EasyExcel 导出报内存溢出如何解决 https://bbs.huaweicloud.com/forum/thread-02111165634289077003-1-1.html