-
华为GaussDB有当天的拨打数据 但是调华为CMS接口却返回为空这是什么原因呢
-
大家好,9月份合集又来了,本次主要带来的是python,redis,mysql,oralce等相关技术分享,希望可以帮到大家 1.Python语言中的重要函数对象用法小结【转】 https://bbs.huaweicloud.com/forum/thread-0292163074507230065-1-1.html 2.PyTorch中torch.no_grad()用法举例详解【转】 https://bbs.huaweicloud.com/forum/thread-02127163074675610068-1-1.html 3.解决遇到:PytorchStreamReader failed reading zip archive:failed finding central错误问题【转】 https://bbs.huaweicloud.com/forum/thread-0290163076531320030-1-1.html 4.解决遇到PermissionError:[Errno 13] Permission denied:XXXX错误的问题【转】 https://bbs.huaweicloud.com/forum/thread-0204163087169319057-1-1.html 5.使用python复制PDF中的页面的操作代码【转】 https://bbs.huaweicloud.com/forum/thread-0204163087217277058-1-1.html 6.Python中的Popen函数demo演示【转】 https://bbs.huaweicloud.com/forum/thread-0287163087322224052-1-1.html 7.Redis内存碎片率调优处理方式【转】 https://bbs.huaweicloud.com/forum/thread-02127163089843529071-1-1.html 8.oracle关联查询报invalid number错误的解决方法【转】 https://bbs.huaweicloud.com/forum/thread-0290163089973043031-1-1.html 9.sql中的regexp与like区别实现【转】 https://bbs.huaweicloud.com/forum/thread-02127163091329965072-1-1.html 10.SQL多表联查的几种方法示例总结【转】 https://bbs.huaweicloud.com/forum/thread-0234163091395788038-1-1.html 11.redis中如何做到内存优化【转】 https://bbs.huaweicloud.com/forum/thread-02127163091498087074-1-1.html 12.mysql数据库实现超键、候选键、主键与外键的使用【转】 https://bbs.huaweicloud.com/forum/thread-0290163091552614032-1-1.html 13.达梦数据库如何设置自增主键的方法及注意事项【转】 https://bbs.huaweicloud.com/forum/thread-0234163091642509039-1-1.html 14.解决生产环境遇到的curl和yum命令报错问题【转】 https://bbs.huaweicloud.com/forum/thread-0234163091687787040-1-1.html 15.Nginx实现404页面的配置方法的两种方法【转】 https://bbs.huaweicloud.com/forum/thread-0290163091762002033-1-1.html
-
1、数据结构的优化1、使用数据结构的最小存储形式。例如,如果你需要存储一组唯一的用户ID,你可以将这些信息合并到一个大的哈希表中,而不是为每个用户创建单独的哈希表,以减少固定开销。2、使用整数编码。例如,存储用户的年龄信息时,将年龄存储为整数值而不是字符串,可以节省内存。3、使用Redis的HyperLogLog来进行基数估计,这比存储大量唯一值的集合更加节省内存。2、启用对象压缩Redis 6及以上版本引入了对字符串的内置LZF压缩支持。通过配置参数activerehashing可以启用对象压缩,减少存储空间。3、设置适当的过期时间为缓存的数据设置适当的过期时间,以防止内存泄漏。这可以确保在数据不再需要时及时释放内存。4、分片将数据分片到多个Redis实例中,以便每个实例只存储部分数据。这可以减小每个实例的内存需求,特别是在大规模部署时。5、使用持久化方式如果你使用了Redis的持久化机制,考虑使用RDB快照来定期将内存中的数据快照到磁盘,以便在需要时进行恢复。6、内存碎片整理定期执行MEMORY DOCTOR命令来检查和修复内存碎片。这可以通过将碎片的数据移动到一个新的实例中来实现。7、客户端和配置优化1、接入Redis服务器的TCP连接输入输出缓冲内存占用需要注意,特别是在异地部署主从或高并发场景下。2、使用client-output-buffer-limit参数配置输出缓冲占用,避免主节点上挂载过多的从节点。3、对于复制积压缓冲区(v2.8之后提供的一个可重用的固定大小缓冲区),合理配置repl-backlog-size参数,以避免全量复制。4、对于AOF缓冲区,根据AOF重写时间及增量来合理配置缓存大小。
-
1.背景概述在生产环境中Redis Cluster集群触发了内存碎片化的告警(碎片率>1.5),集群节点分布三台宿主机六个节点三主三从架构,Redis版本是6.2.X。2.redis内存碎片的形成内存碎片形成的原因主要有2点:内因:操作系统的内存分配机制。外因:Redis的负载特征造成。内因:内存分配器会按照固定大小来分配内存,而不是按需分配。例如Linux下默认是4KB,开启内存大页机制后就变成2MB。Redis中使用jemalloc分配器来分配内存。它会按照一系列固定大小的内存来进行分配。例如当Redis中需要申请一个20B大小的空间来保存数据,那么jemalloc分配器就会分配32B:倘若此时应用还要写入5B大小的数据,那么无需申请额外的空间。倘若此时应用还要写入20B大小的数据,那么必须在申请额外的空间了,此时就会有产生内存碎片的风险(之前分配的32B中,10B就是内存碎片了)外因:我们有一个Redis实例,里面有着不同大小的键值对,那么根据内存分配器的分配机制来看。就有可能分配着不同大小的连续内存空间。另一方面,我们对键值对也有可能有着不同的操作,增删改查。3.清理内存碎片清理内存碎片之前,首先应该做的就是判断是否有内存碎片:我们可以登录Redis后使用INFO MEMORY命令查看。mem_fragmentation_ratio参数的值就是内存碎片化的值。mem_fragmentation_ratio代表Redis实例当前的内存碎片率。其计算公式为:mem_fragmentation_ratio = used_memory_rss / used_memoryused_memory_rss:操作系统实际分配Redis的物理内存空间。used_memory:Redis为了保存数据而实际申请的空间。针对mem_fragmentation_ratio,有两个参考:mem_fragmentation_ratio ∈ (1, 1.5]:属于合理范围内,暂时可以放放。mem_fragmentation_ratio ∈ (1.5, +∞):表明内存碎片率超过了50%,需要采取措施降低内存碎片率。那么如何清理内存碎片呢(一般不会重启实例,因为生产上往往不允许这种神操作出现),在Redis4.0版本以后,Redis提供了内置的内存碎片清理机制。12345678910111213#内存碎片回收机制使用activedefrag yes# active-defrag-ignore-bytes与active-defrag-threshold-lower两个条件同时满足会触发内存碎片清理,当有一个不满足则停止清理# 启动活动碎片整理的最小碎片浪费量,内存碎片的字节数达到100M时开始清理active-defrag-ignore-bytes 100mb# 启动活动碎片整理的最小碎片百分比,内存碎片空间占操作系统分配给redis的总空间比例达到 10% 时开始清理active-defrag-threshold-lower 10# 内存碎片超过 100%,则尽最大努力整理active-defrag-threshold-upper 100# 以CPU百分比表示的碎片整理的最小工作量,自动清理过程所用CPU时间的比例不低于5%,保证能正常清理active-defrag-cycle-min 5# 自动清理过程所用CPU时间的比例不高于75%,超过75%停止清理,避免redis主线程阻塞active-defrag-cycle-max 75以上参数可根据主机资源配置及应用场景自行调整。除此之外,值得注意的是,虽然Redis提供了这样的自动内存清理机制,能够带来清理内存碎片的好处,但是与此同时的必定有着其对应的牺牲,也就是性能影响问题。Redis提供了内置的内存碎片清理机制的使用前提是在编译的过程中添加了内存分配器参数MALLOC=jemalloc1make MALLOC=jemalloc4.扩展当然我们在生产环境使用Redis过程中也可以使用自带的命令进行内存使用情况的诊断,便于我们及时对问题进行优化处理。我们可以使用MEMORY help查看:1234567127.0.0.1:6379> MEMORY help1) MEMORY <subcommand> arg arg ... arg. Subcommands are:2) DOCTOR - Return memory problems reports.3) MALLOC-STATS -- Return internal statistics report from the memory allocator.4) PURGE -- Attempt to purge dirty pages for reclamation by the allocator.5) STATS -- Return information about the memory usage of the server.6) USAGE <key> [SAMPLES <count>] -- Return memory in bytes used by <key> and its value. Nested values are sampled up to <count> times (default: 5).MEMORY STATSredis的内存使用不只包含全部的key-value数据,还有描述这些key-value的元信息,以及许多管理功能的消耗,好比持久化、主从复制,经过MEMORY STATS能够更好的了解到redis的内存使用情况
-
因参与楼层不满足开奖条件,本活动不开奖。-------------------------------------------------------------------参加“掌握Redis部署,轻松实现电商平台秒杀抢购!”项目在本活动帖下回帖,提出你的问题与建议有机会获得开发者定制礼品【体验项目】掌握Redis部署,轻松实现电商平台秒杀抢购!【体验简介】通过本案例,开发者将掌握在云主机中安装和配置Redis,了解如何在Java项目中使用Jedis对接Redis服务器实现缓存功能并且使用CodeArts IDE模拟运行电商秒杀抢购场景。【体验形式】1.登录注册华为云账号,领取云主机;2、使用云主机资源进行应用开发。【活动时间】2024年9月13-10月12日【参与方式】直接在此活动帖下方回帖,将体验完成的截图和您的问题/建议/感受一起回帖即可比如体验中遇到的问题,对产品的建议、对活动感受等等PS:不要少于30字哦~【获奖规则】可提前填写获奖信息收集表,后续如您中奖,我们会及时发货,谢谢。获奖信息收集表: cid:link_0【活动规则】1、本帖的回帖建议不少于30字,仅限于对“掌握Redis部署,轻松实现电商平台秒杀抢购!”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;实物奖品具体发放视出库情况而定; 3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
-
1. 创建Spring Boot项目首先,创建一个新的Spring Boot项目。你可以使用Spring Initializr(https://start.spring.io/)来生成项目结构。选择以下依赖:Spring WebSpring Data RedisLombok(可选,用于简化代码)2. 配置application.yml在你的 application.yml文件中添加Redis配置:12345678spring: cache: type: GENERIC redis: host: ${sy.redis.ip} password: port: ${sy.redis.port} database: ${sy.redis.database}3. 创建缓存配置类创建一个配置类来手动配置基于Redis的缓存管理器:import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import java.time.Duration; @Configuration public class CacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(10)) // 设置缓存过期时间 .disableCachingNullValues() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(cacheConfiguration) .build(); } }4. 创建服务类创建一个服务类来使用Redis的 INCR方法生成每天的序号import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @Service public class SequenceService { @Autowired private StringRedisTemplate redisTemplate; public long getDailySequence() { String dateStr = DateUtils.format(new Date(), "yyyy-MM-dd"); String key = "dailySequence_" + dateStr; // 执行 increment 操作 Long applicantNumber = redisTemplate.opsForValue().increment(key); // 设置过期时间为2天,不设置默认永久 redisTemplate.expire(key, 2, TimeUnit.DAYS); //redisTemplate.expire(key) // 查询key的过期时间。 //-1: 表示键存在但没有设置过期时间。 //-2: 表示键不存在。 //返回秒:如上面返回值是 172780,这意味着该键将在大约 172780 秒(约 48 小时)后过期。 return applicantNumber; } }5. 创建控制器创建一个控制器来暴露获取每天序号的API:import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SequenceController { @Autowired private SequenceService sequenceService; @GetMapping("/daily-sequence") public String getDailySequence() { long sequence = sequenceService.getDailySequence(); return "Daily sequence: " + sequence; } }6. 启动类确保你的启动类包含 @EnableCaching注解以启用缓存功能:import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class RedisIncrApplication { public static void main(String[] args) { SpringApplication.run(RedisIncrApplication.class, args); } }
-
一、Redis 哨兵模式:哨兵的核心功能:在主从复制的基础上,哨兵引入了主节点的自动故障转移1、哨兵模式原理:哨兵:是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的Master 并将所有Slave 连接到新的 Master。所以整个运行哨兵的集群的数量不得少于3个节点。2、哨兵模式的作用:监控:哨兵会不断地检查主节点和从节点是否运作正常。自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。通知提醒:哨兵可以将故障转移的结果发送给客户端3、哨兵的结构:哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点就是特殊的redis节点,不存储数据数据节点:主节点和从节点都是数据节点注意:哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式,所有节点上都需要部署哨兵模式,哨兵模式会监控所有的Redis工作节点是否正常。4、故障转移机制:由哨兵节点定期监控主节点是否出现了故障,每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。 如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的),当超过半数哨兵节点认为该主节点下线了,这样就客观下线了。 此时哨兵节点会通过Raft算法〈选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。故障转移过程如下:● 将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;● 若原主节点恢复也变成从节点,并指向新的主节点;● 通知客户端主节点已经更换。主节点的选举条件:过滤掉不健康的(已下线的),没有回复哨兵ping响应的从节点选择配置文件中从节点优先级最高的(replication-priority,默认值为100)选择复制偏移量最大的,也就是复制最完整的从节点。二、案例环境
-
1、redis的删除策略Redis 是一种内存级数据库,数据都存在内存中,但是针对于已经过期的数据,reids 不 会立刻删除只是会存储在 expires 中,当执行删除策略的时候,才会从 expires 中寻找对应的数据存储的地址,在存储空间中找到对应的数据进行删除。数据删除其实就是内存和 CPU 占用之间寻找平衡,CPU 才能去处理事情,针对过期数据,要进行删除的时候,一般有三种策略 2、三种删除策略 (1)、定时删除顾名思义,给Key设置一个时间,时间到了,定时器任务立即执行删除,相当于消 耗 CPU 来减少内存使用,拿时间换空间。优点:节约内存,到时就删除,快速释放掉不必要的内存占用 缺点:CPU 压力大,无论 CPU 此时负载量多高,都会去占用 CPU 进行 key 的删除 操作,会影响 Redis 服务器响应时间和吞吐量,是一种比较低效的方式 结论:用 CPU 性能换取内存空间,时间换空间(2)、惰性删除 就是说,数据到达过期时间的时候,先不做处理,等到下次访问数据的时候,进行访问, 如未过期,返回数据,如过期,则删除。这就相当于节约了 CPU 但占用了内存,拿空间换 时间。优点:不占用 CPU 节约 CPU 性能,只在获取访问 key 的时候才判断是否过期,过期 则删除,只会删除当前获取的这一个 key,其他的 key 还是保持原样缺点:内存占用大,如果一直没有获取它,那么数据就会长期占用内存空间,当有大量 的 key 没有被使用到,也造成了大量内存浪费,对内存数据库来说,也不太友好 结论:空间换时间(3)、定期删除 前面说的两种方案 1.时间换空间,2.空间换时间都是两个极端方法,为避免前面方案带 来的问题,Redis 引入了定期删除策略(是他们的一个比较折中的方案)周期性轮询 Redis 库中的时效性数据,采取随机抽取的策略,利用过期数据占比的方式控制删除频度。在 Redis 服务器初始化时,读取 server.hz 的值,默认值为 10。定时轮询服务器,每秒钟执行 server.hz 次 serverCron() 函数。databaseCron() 在后台轮询处理 16 个 redis 数据库的操作,如这里的过期key 的处理activeExpireCycle(),对每个数据库的 expire 空间进行检测,每次执行250ms/server.hz 随机选取一批 expire 空间的 key(redis 有 16 个数据库,从 0 号数据库开始—15号数据库) 删除这批 key 中已过期的。如果这批 key 中已过期的占比超过 25%,那么再重复执行步骤一。(循环到小于 25%结束当前数据库的删除)如果这批 key 中已过期的占比 ≤ 25%,检测下一个数据库的 expire 空间(current_db++) 用 info 命令查看相关配置参数 每秒钟执行 hz 次 serverCron(),对服务器进行定时轮询3、三种策略对比 1:定时删除: 节约内存,无占用, 不分时段占用 CPU 资源, 频度高,拿时间换空间 2:惰性删除: 内存占用严重 延时执行, CPU 利用率高拿空间换时间3:定期删除: 内存定期随机清理 每秒花费固定的 CPU 资源维护内存 随机抽查,重点抽查4、淘汰/逐出策略 在 Redis 中经常会进行数据的增删查改操作,那么如果在添加数据的时候遇到了内存不足,该怎么办?在前面用的删除策略可以避免出现这种情况吗? 实际上,在前面所说的删除策略,它针对的是 expire 命令进行的操作,也就是说那些具有时效性的数据(已经过期,并且还在占用内存的数据) 针对那些并没有过期,或者是内存中的数据没有一个带有有效期,全是永久性数据,这时候删除策略就不起作用了,所以这个时候内存满了我们再去插入数据到内存是怎么做?那就需要用到淘汰策略了。redis 执行命令之前,都会用 freeMemoryIfNeeded()方法,检测这次内存是否充足,如果不满足加入新数据,则会执行淘汰策略(淘汰未过期的数据)(1)、淘汰策略分类检测带有时效性的数据进行淘汰(一般是有定时,会过期的数据的)volatile-lru:挑选最近最少使用的数据淘汰volatile-lfu:挑选最近使用次数最少的数据淘汰volatile-ttl:挑选将要过期的数据淘汰volatile-random:任意选择数据淘汰检测全库的数据进行淘汰allkeys-lru:挑选最近最少使用的数据淘汰allkeLyRs-lfu:挑选最近使用次数最少的数据淘汰allkeys-random:任意选择数据淘汰,相当于随机
-
Redis的性能优化涉及到硬件选择、配置调整、客户端优化、持久化策略等多个层面。1. 硬件优化解决方案:选择更快的CPU、更多的内存、更快的磁盘(SSD推荐)和足够的网络带宽。2. 合理的实例部署解决方案:根据业务访问模式,决定是使用单实例、主从复制、哨兵系统还是Redis集群。3. 连接数优化解决方案:调整redis.conf中的maxclients参数,以适应业务需求。示例配置:maxclients 100004. 命令优化解决方案:避免使用耗时的命令,如KEYS、FLUSHDB等,使用SCAN替代。5. 使用连接池解决方案:使用客户端连接池减少连接建立和销毁的开销。示例代码(Java Jedis连接池):JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(100); poolConfig.setMaxIdle(10); poolConfig.setMinIdle(5); JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379); Jedis jedis = jedisPool.getResource(); // 执行命令 jedis.set("foo", "bar"); // 关闭连接 jedis.close();6. Pipelining批量命令解决方案:使用Pipeline批量执行命令,减少网络延迟。示例代码(Java Jedis Pipeline):Jedis jedis = jedisPool.getResource(); Pipeline pipeline = jedis.pipeline(); pipeline.set("foo", "bar"); pipeline.get("foo"); List<Object> results = pipeline.syncAndReturnAll(); jedis.close();7. 键值对设计解决方案:选择合适的数据类型,使用散列(Hash)存储相关联的字段。示例代码:// 使用Hash存储用户信息 hset "user:1000" "name" "John Doe" hset "user:1000" "email" "john@example.com"8. 内存优化解决方案:使用内存淘汰策略,如volatile-lru或allkeys-lru。示例配置:maxmemory-policy allkeys-lru9. 持久化策略解决方案:根据数据的重要性选择合适的持久化方式(RDB、AOF或两者结合)。示例配置:appendonly yes appendfsync everysec10. 禁用持久化解决方案:对于可以容忍数据丢失的场景,可以完全禁用持久化。示例配置:save "" appendonly no11. Lua脚本解决方案:使用Lua脚本来打包多个命令,减少网络延迟。示例代码:-- Lua脚本,实现原子增减操作 return redis.call('INCR', KEYS[1])12. 慢查询日志解决方案:开启慢查询日志,分析慢查询原因。示例配置:slowlog-log-slower-than 10000 slowlog-max-len 12813. 主从复制解决方案:使用主从复制提高读性能,同时实现数据的热备份。示例配置:slaveof <masterip> <masterport>14. Redis集群解决方案:使用Redis集群实现数据的自动分区和高可用。示例命令:./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:700215. 监控和报警解决方案:使用Redis自带的监控工具或第三方监控系统,实时监控Redis状态。示例命令:redis-cli info16. 禁用THP解决方案:禁用Transparent HugePages,避免内存页管理的性能损耗。示例命令:echo never > /sys/kernel/mm/transparent_hugepage/enabled17. 操作系统优化解决方案:调整操作系统参数,如文件描述符限制、TCP缓冲区大小等。示例命令:sysctl -w net.core.somaxconn=1024 ulimit -n 409618. 网络优化解决方案:优化TCP堆栈参数,如TCP接收和发送缓冲区大小。示例命令:sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456' sysctl -w net.ipv4.tcp_wmem='4096 16384 4194304'19. 数据压缩解决方案:对于大体积的数据,使用数据压缩算法减少存储大小和传输时间。示例:使用ZIPLIST编码的数据结构存储小对象。20. 优化键设计解决方案:设计具有前缀的键名,便于管理和迁移。示例:// 使用命名空间来区分不同的数据类型 set user:1000:name "John Doe" set user:1000:email "john@example.com"21. 避免大Key和大Value解决方案:大Key和大Value会影响Redis的性能和稳定性,应尽量避免。示例:将大的列表或集合分割成多个小的集合。22. 使用二进制序列化解决方案:使用二进制序列化协议提高数据传输效率。示例:使用MSGPACK或PROTOBUF序列化Java对象。23. 优化数据访问模式解决方案:根据业务特点,优化数据的访问模式,如使用缓存预热、缓存雪崩的解决方案等。24. 合理的数据过期策略解决方案:为数据设置合理的过期时间,避免过期数据占用内存。示例配置:expire user:1000:email 8640025. 减少网络延迟解决方案:优化网络环境,使用QoS策略减少网络延迟。26. 使用SSD而不是HDD解决方案:使用固态硬盘(SSD)代替机械硬盘(HDD),提高磁盘I/O性能。27. 优化持久化日志解决方案:调整AOF持久化的策略,比如使用everysec或no选项。示例配置:appendfsync no28. 使用Redis 4.0以上的版本解决方案:新版本的Redis提供了更多的功能和性能改进,如增加了模块系统、支持多线程等。29. 避免使用阻塞命令解决方案:在可能的情况下,避免使用可能导致阻塞的命令,如BLPOP、BRPOP等。30. 定期进行性能评估解决方案:定期对Redis实例进行性能评估,根据评估结果调整配置。示例工具:使用redis-benchmark工具进行基准测试。31. 使用Redisson客户端解决方案:对于Java应用,使用Redisson客户端可以提供更高级的功能,如分布式锁、原子操作等。示例代码(Redisson配置):Config config = new Config(); SingleServerConfig singleServerConfig = config.useSingleServer(); singleServerConfig.setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config);32. 避免全量扫描解决方案:在可能的情况下,避免使用KEYS命令进行全量扫描,这会导致性能急剧下降。33. 优化数据迁移解决方案:在进行数据迁移时,使用MIGRATE命令,它可以原子性地迁移数据。示例命令:MIGRATE "127.0.0.1" 6379 "127.0.0.1" 6380 "key" 0 5000 REPLACE34. 优化日志级别解决方案:根据需要调整日志级别,避免冗余日志占用过多磁盘空间和CPU资源。示例配置:loglevel warning35. 优化Redis配置文件解决方案:定期审查和优化redis.conf配置文件,以匹配当前的业务需求。最后以上是Redis企业级性能优化的一些关键点和解决方案。转载自https://www.cnblogs.com/wgjava/p/18267106
-
【问题】① 双击redis-server.exe闪退。② 终端运行redis-server没反应。但是终端运行redis -cli没问题。【解决方法】步骤1:找到Redis文件夹,右击,在终端打开。步骤2:输入命令:redis-server.exe redis.windows.conf 就按下面步骤输入命令并回车:步骤1:redis-cli.exe步骤2:shutdown(结束)步骤3:exit (退出)步骤4:redis-server.exe redis.windows.conf 重新启动就可以了!
-
本文主要介绍了 Redission实现分布式锁lock()和tryLock()方法的区别小结,具体如下:1lock.lock(30, TimeUnit.SECONDS); // 尝试获取锁30秒,如果获取不到则放弃12//尝试获取锁,等待5秒,持有锁10秒钟boolean success = lock.tryLock(5, 10, TimeUnit.SECONDS);Redisson 是一种基于 Redis 的分布式锁框架,提供了 lock() 和 tryLock() 两种获取锁的方法。lock() 方法是阻塞获取锁的方式,如果当前锁被其他线程持有,则当前线程会一直阻塞等待获取锁,直到获取到锁或者发生超时或中断等情况才会结束等待。该方法获取到锁之后可以保证线程对共享资源的访问是互斥的,适用于需要确保共享资源只能被一个线程访问的场景。Redisson 的 lock() 方法支持可重入锁和公平锁等特性,可以更好地满足多线程并发访问的需求。而 tryLock() 方法是一种非阻塞获取锁的方式,在尝试获取锁时不会阻塞当前线程,而是立即返回获取锁的结果,如果获取成功则返回 true,否则返回 false。Redisson 的 tryLock() 方法支持加锁时间限制、等待时间限制以及可重入等特性,可以更好地控制获取锁的过程和等待时间,避免程序出现长时间无法响应等问题。因此,两种获取锁的方式各有优缺点,在实际应用中需要根据具体场景和业务需求来选择合适的方法,以确保程序的正确性和高效性。直接看代码例子lock.tryLock等待时间和持有时间都为0时。 public String RedissonLock1() { RLock lock = redissonClient.getLock("order_lock"); boolean success = true; try { System.out.println("获取锁前的时间:"+LocalDateTime.now()); // 尝试获取锁,等待0秒,持有锁0秒钟 success = lock.tryLock(0, 0, TimeUnit.SECONDS); // lock.lock(0, TimeUnit.SECONDS); System.out.println("获取锁后的时间:"+LocalDateTime.now()); if (success) { System.out.println(Thread.currentThread().getName() + "获取到锁"+ LocalDateTime.now()); // 模拟业务处理耗时 // TimeUnit.SECONDS.sleep(3); // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。 TimeUnit.SECONDS.sleep(20); } else { System.out.println(Thread.currentThread().getName() + "未能获取到锁,已放弃尝试"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { // 判断当前线程是否持有锁 if (success && lock.isHeldByCurrentThread()) { //释放当前锁 lock.unlock(); System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now()); } } return ""; } lock()方法的持有锁时间为0时 public String RedissonLock2() { RLock lock = redissonClient.getLock("order_lock"); boolean success = true; try { System.out.println("获取锁前的时间:"+LocalDateTime.now()); // 尝试获取锁,等待5秒,持有锁10秒钟 // success = lock.tryLock(0, 0, TimeUnit.SECONDS); lock.lock(0, TimeUnit.SECONDS); System.out.println("获取锁后的时间:"+LocalDateTime.now()); // 模拟业务处理耗时 // TimeUnit.SECONDS.sleep(3); // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。 TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 判断当前线程是否持有锁 if (success && lock.isHeldByCurrentThread()) { //释放当前锁 lock.unlock(); System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now()); } } return ""; }lock() 和 tryLock()都会用的 tryAcquireAsync(),看到区别,其实核心是leaseTime是否 > 0 所以是否使用看门狗不算是tryLock和lock()的区别,可以看下面这5种情况。 //走if (leaseTime > 0)逻辑 lock.tryLock(5, 10, TimeUnit.SECONDS); lock.lock(10, TimeUnit.SECONDS); //不走if (leaseTime > 0)逻辑 lock.tryLock(0, -1, TimeUnit.SECONDS); lock.lock(-1, TimeUnit.SECONDS); //lock()不带参数,默认leaseTime = -1 lock.lock(); 当oldEntry == null时,执行renewExpiration(); 就是个定时器,即是看门狗核心逻辑了。 private void renewExpiration() { ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName()); if (ee == null) { return; } Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName()); if (ent == null) { return; } Long threadId = ent.getFirstThreadId(); if (threadId == null) { return; } CompletionStage<Boolean> future = renewExpirationAsync(threadId); future.whenComplete((res, e) -> { if (e != null) { log.error("Can't update lock {} expiration", getRawName(), e); EXPIRATION_RENEWAL_MAP.remove(getEntryName()); return; } if (res) { // reschedule itself renewExpiration(); } else { cancelExpirationRenewal(null); } }); } }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS); ee.setTimeout(task); } 其中有下面红圈这段逻辑,也就是看门狗之所以在三分之一的时候执行的原因, 没有自定义时1config.setLockWatchdogTimeout(10000); // 设置锁的看门狗超时时间为10秒默认就是30秒 除以3 也就是10秒时执行。ChaGPT解释此段LUA:这是 Redisson 中 RedissonLock 类实现的 tryLockInnerAsync() 方法。该方法用于尝试获取锁,它会先检查锁是否已经被其他线程持有,如果没有被持有,则将当前线程设置为锁的持有者,并返回 null;否则返回当前线程需要等待的时间,以便稍后再次尝试获取锁。具体地说,Lua 脚本的逻辑是这样的:如果锁不存在或者锁已经被当前线程持有(使用 hash 存储锁的持有者),则将当前线程作为锁的持有者,并且设置锁的过期时间,并返回 null。这里的代码具体操作包括使用 HEXISTS 命令检查锁的持有情况,使用 HINCRBY 命令来设置持有者和持有计数器并提高计数器的值,以及使用 PEXPIRE 命令来设置锁的过期时间。如果锁已经被其他线程持有,则返回当前线程需要等待的时间,以便稍后再次尝试获取锁。这里使用 PTTL 命令来查询锁的过期时间,并返回给调用方。需要注意的是,因为 tryLockInnerAsync 方法的实现是原子的,所以它可以保证在分布式环境下的正确性。同时,它也支持重入锁的功能,因为它保留了锁的持有者和持有计数器的值。
-
流表配置如下,使用hash结构:flinksql语句,简单统计时间和数量:所得结果:问题:想要使用begin_time作为hash的key,sum作为value该如何配置
-
一、Redis 内存碎片内存碎片是指在内存分配的时候,产生的不能重复利用的空间。例如,内存空间还有3K,应用程序想申请连续的3K空间,虽然内存空间够,但是空间分配为2K,1K,总空间够,但是不连续,导致应用程序申请失败,这种无法利用的内存空间称之为"内存碎片"。内存分片会占用操作系统分配给redis的内存空间,严重影响redis性能。二、内存碎片形成原因1.内因内存分片策略引发:redis默认使用jemalloc分配器分配内存。jemalloc每次分配2*N固定空间,例如写入数据申请10K空间,jemalloc会分配16K空间,优点:下次写入>=6K数据不需要申请内存空间,缺点造成内存浪费。2.外因修改内存中数据:修改包括增加和减少内存占用,例如原来的16K空间数据,增加或减少1K都会造成内存浪费。大量内存碎片的存在,会造成redis实际内存使用率降低,影响性能。三、查看内存碎片info memory 查看redis内存使用情况,主要关注以下参数mem_fragmentation_ratio计算公式为:used_memory_rss/used_memory 该值大于1但小于1.5。这种情况是合理的。该值过高时考虑清理内存,例如该值大于1.5表示有50%空间浪费,需要清理内存碎片。used_memory: redis分配的内存总量单位为bused_memory_human: redis分配的内存总量单位为Mused_memory_rss: redis向操作系统申请的内存总量单位为bused_memory_rss_human: redis向操作系统申请的内存总量单位为Mmem_fragmentation_ratio: 内存碎片率mem_allocator:jemalloc-5.1.0 内存分配器四、内存碎片清理内存碎片清理,就是将不连续的内存空间重新整理为连续空间,由于redis是单线程,在清理过程中会造成堵塞,降低性能。可通过以下三种方式清理:1.手动清理内存碎片memory purge 只支持jemalloc内存分配器2.自动清理修改redis.conf配置文件activedefrag yes 开启自动清理内存碎片,命令开启:config set activedefrag yesactive-defrag-ignore-bytes 100mb 内存碎片的字节数达到100M时开始清理active-defrag-threshold-lower 10 内存碎片空间占操作系统分配给redis的总空间比例达到 10% 时开始清理active-defrag-ignore-bytes与active-defrag-threshold-lower 两个条件同时满足会触发内存碎片清理,当有一个不满足则停止清理active-defrag-threshold-upper 100 内存碎片超过 100%,则尽最大努力整理active-defrag-cycle-min 1 自动清理过程所用CPU时间的比例不低于1%,保证能正常清理active-defrag-cycle-max 25 自动清理过程所用CPU时间的比例不高于25%,超过25%停止清理,避免redis主线程阻塞active-defrag-max-scan-fields 1000 自动清理过程中长度小于1000的set/hash/zset/list才会进行自动清理3.重启redis
-
1 优雅的key结构Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定:遵循基本格式:[业务名称]:[数据名]:[id]长度不超过44字节不包含特殊字符这样设计的好处:可读性强避免key冲突方便管理更节省内存: key是string类型,底层编码包含int、embstr和raw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小。当字节数大于44字节时,会转为raw模式存储,在raw模式下,内存空间不是连续的,而是采用一个指针指向了另外一段内存空间,在这段空间里存储SDS内容,这样空间不连续,访问的时候性能也就会收到影响,还有可能产生内存碎片2 拒绝BigKeyBigKey通常以Key的大小和Key中成员的数量来综合判定,例如:Key本身的数据量过大:一个String类型的Key,它的值为5 MBKey中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB那么如何判断元素的大小呢?redis也给我们提供了命令推荐值:单个key的value小于10KB对于集合类型的key,建议元素数量小于10002.1 BigKey的危害网络阻塞对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢数据倾斜BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡Redis阻塞对元素较多的hash、list、zset等做运算会耗时较旧,使主线程被阻塞CPU压力对BigKey的数据序列化和反序列化会导致CPU的使用率飙升,影响Redis实例和本机其它应用命令:redis-cli -a 密码 --bigkeys2.3 如何删除BigKeyBigKey内存占用较多,即便时删除这样的key也需要耗费很长时间,导致Redis主线程阻塞,引发一系列问题。redis 3.0 及以下版本如果是集合类型,则遍历BigKey的元素,先逐个删除子元素,最后删除BigKeyRedis 4.0以后Redis在4.0后提供了异步删除的命令:unlink3 恰当的数据类型例1:比如存储一个User对象,我们有三种存储方式:①方式一:json字符串user:1{“name”: “Jack”, “age”: 21}优点:实现简单粗暴缺点:数据耦合,不够灵活②方式二:字段打散user:1:nameJackuser:1:age21优点:可以灵活访问对象任意字段缺点:占用空间大、没办法做统一控制
-
1.redis简介为了提高网站响应速度,企业会将热点数据保存在内存中而不是直接从后端数据库中读取。大型网站应用,热点数据往往巨大,几十G上百G是很正常的事,这种情况下,就需要用到缓存服务器,通过缓存服务器承载大部分用户请求,小部分用户请求交给后端服务器处理,如此一来,就可以大大提高用户访问的速度,提升用户使用体验。常用的缓存服务器有:memcacheredisRedis 是一种开源(BSD 许可)内存中数据结构存储,用作数据库、缓存、消息代理和流引擎。为了实现最佳性能,Redis 使用 内存数据集。根据您的使用案例,Redis 可以通过定期将数据集转储到磁盘或将每个命令附加到基于磁盘的日志来持久保存您的数据。如果您只需要功能丰富的网络内存缓存,您还可以禁用持久性。Redis 支持异步复制,具有快速非阻塞同步和自动重新连接以及网络分割上的部分重新同步。2 redis集群2.1 redis集群分类集群是一组相互独立、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群就像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。redis集群有三种集群模式:主从模式哨兵(Sentinel)模式Cluster模式(群集模式)在服务开发中,单机都会存在单点故障的问题,即服务部署在一台服务器上,一旦服务器宕机服务就不可用,所以为了让服务高可用,分布式服务就出现了,将同一服务部署到多台机器上,即使其中几台服务器宕机,只要有一台服务器可用服务就可用。redis也是一样,为了解决单机故障引入了主从模式,但主从模式存在一个问题:master节点故障后服务,需要人为的手动将slave节点切换成为maser节点后服务才恢复。redis为解决这一问题又引入了哨兵模式,哨兵模式能在master节点故障后能自动将salve节点提升成master节点,不需要人工干预操作就能恢复服务可用。但是主从模式、哨兵模式都没有达到真正的数据sharding存储,每个redis实例中存储的都是全量数据,所以redis cluster就诞生了,实现了真正的数据分片存储。2.2 主从模式redis单节点虽然有通过RDB和AOF持久化机制能将数据持久化到硬盘上,但数据是存储在一台服务器上的,如果服务器出现硬盘故障等问题,会导致数据不可用,而且读写无法分离,读写都在同一台服务器上,请求量大时会出现I/O瓶颈。为了避免单点故障 和 读写不分离,Redis 提供了复制(replication)功能实现master数据库中的数据更新后,会自动将更新的数据同步到其他slave数据库上。通过数据复制,Redis 的一个 master 可以挂载多个 slave,而 slave 下还可以挂载多个 slave,形成多层嵌套结构。所有写操作都在 master 实例中进行,master 执行完毕后,将写指令分发给挂在自己下面的 slave 节点。slave 节点下如果有嵌套的 slave,会将收到的写指令进一步分发给挂在自己下面的 slave。通过多个 slave,Redis 的节点数据就可以实现多副本保存,任何一个节点异常都不会导致数据丢失,同时多 slave 可以 N 倍提升读性能。master 只写不读,这样整个 master-slave 组合,读写能力都可以得到大幅提升。主从模式优缺点:优点: 主从结构具有读写分离,提高效率、数据备份,提供多个副本等优点。不足: 最大的不足就是主从模式不具备自动容错和恢复功能,主节点故障,集群则无法进行工作,可用性比较低,从节点升主节点需要人工手动干预。普通的主从模式,当主数据库崩溃时,需要手动切换从数据库成为主数据库:在从数据库中使用SLAVE NO ONE命令将从数据库提升成主数据继续服务。启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可同步数据。2.3 哨兵模式主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。哨兵模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来。哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel进程。哨兵本身也有单点故障的问题,所以在一个一主多从的Redis系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。2.3.1 哨兵模式的作用监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,除了监控主服务器、从服务器外,哨兵之间也相互监控。故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。2.3.2 哨兵模式优缺点优点:哨兵模式是基于主从模式的,解决主从模式中master故障不能自动切换故障的问题。缺点:哨兵模式下每台 Redis 服务器都存储相同的数据,很浪费内存空间;数据量太大,主从同步时严重影响了master性能。哨兵模式是中心化的集群实现方案,每个从机和主机的耦合度很高,master宕机到salve选举master恢复期间服务不可用。因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。哨兵模式始终只有一个Redis主机来接收和处理写请求,写操作还是受单机瓶颈影响,没有实现真正的分布式架构。2.4 Cluster模式主从模式或哨兵模式每个节点存储的数据都是全量的数据,数据量过大时,就需要对存储的数据进行分片后存储到多个redis实例上。此时就要用到Redis Sharding技术。redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。Redis Cluster集群具有如下几个特点:集群完全去中心化,采用多主多从;所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。每一个分区都是由一个Redis主机和多个从机组成,分片和分片之间是相互平行的。每一个master节点负责维护一部分槽,以及槽所映射的键值数据;集群中每个节点都有全量的槽信息,通过槽每个node都知道具体数据存储到哪个node上。redis cluster主要是针对海量数据+高并发+高可用的场景,如果你的数据量很大,那么建议就用redis cluster,数据量不是很大时,使用sentinel就够了。redis cluster的性能和高可用性均优于哨兵模式。Redis Cluster采用虚拟哈希槽分区而非一致性hash算法,预先分配一些卡槽,所有的键根据哈希函数映射到这些槽内,每一个分区内的master节点负责维护一部分槽以及槽所映射的键值数据。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签