• [技术干货] Memcached 与 Redis 优劣势对比
    在分布式缓存领域,Redis 和 Memcached 都是经典的解决方案,但近年来 Redis 的使用率远超 Memcached,主要原因在于 Redis 在功能、性能、扩展性和生态支持上的全面优势。以下是具体对比和分析:1. 数据结构与功能对比Memcached纯键值存储:仅支持简单的 key-value 结构,value 只能是字符串(需手动序列化复杂对象)。无内置数据结构:无法直接存储列表、集合、哈希等,需在应用层实现。功能单一:仅支持基础的缓存操作(GET/SET/DELETE),无持久化、事务、Lua 脚本等高级功能。Redis丰富的数据结构:字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)。位图(Bitmap)、超日志(HyperLogLog)、地理空间索引(GEO)、流(Stream)等高级类型。内置功能:持久化:支持 RDB(快照)和 AOF(日志)两种方式,数据可持久化到磁盘。事务:支持 MULTI/EXEC 命令组,保证原子性。Lua 脚本:可通过脚本实现复杂逻辑(如原子性计数器、限流)。发布/订阅:支持消息队列模式。集群模式:原生支持分片和主从复制,扩展性强。结论:Redis 的数据结构和功能远超 Memcached,能覆盖更多业务场景(如排行榜、实时分析、消息队列等)。2. 性能对比简单场景(纯键值读写)Memcached:内存管理更高效(采用 Slab Allocation 机制,减少内存碎片)。多线程模型(可利用多核 CPU),吞吐量更高。Redis:单线程模型(6.0 之前),但通过 I/O 多路复用(epoll/kqueue)实现高并发。6.0 后支持多线程(仅限网络 I/O),性能进一步提升。实际测试:在简单键值操作中,Memcached 的 QPS 可能略高于 Redis,但差距通常在 10%~20% 以内,且 Redis 的延迟更稳定。复杂场景(数据结构操作)Redis 的优势显著:例如,用 Sorted Set 实现排行榜,或用 HyperLogLog 统计 UV,Memcached 无法直接支持。Redis 的 Lua 脚本可减少网络往返,提升性能。结论:在简单场景下两者性能接近,但 Redis 的复杂功能无需额外开发,综合效率更高。3. 持久化与高可用Memcached无持久化:数据仅存于内存,重启后全部丢失。无高可用:需依赖外部工具(如 Twemproxy)实现故障转移,但无法自动恢复。Redis持久化:RDB:定时生成数据快照,适合备份。AOF:记录所有写操作,数据更安全(可配置每秒同步或每次写入同步)。高可用:主从复制(Master-Slave):支持读写分离。哨兵模式(Sentinel):自动故障检测和主从切换。集群模式(Cluster):支持数据分片和水平扩展。结论:Redis 的持久化和高可用是生产环境必备功能,而 Memcached 需依赖第三方工具,复杂度和风险更高。4. 内存管理与扩展性Memcached内存分配:采用 Slab Allocation,按固定大小分配内存块,减少碎片但可能浪费空间。扩展性:支持水平扩展(通过一致性哈希分片),但需应用层处理分片逻辑(如使用 Twemproxy)。无原生集群支持,扩容较麻烦。Redis内存管理:支持动态内存分配,可配置淘汰策略(如 LRU、LFU、TTL)。提供 INFO memory 命令监控内存使用情况。扩展性:Redis Cluster 原生支持分片,自动处理数据迁移和故障转移。支持垂直扩展(增加单机内存)和水平扩展(增加节点)。结论:Redis 的内存管理更灵活,集群模式更易用,适合大规模部署。5. 生态与社区支持Redis:由 Redis Labs(现 Redis Inc.)维护,社区活跃,版本迭代快(如 Redis 7.0 新增多线程、函数等特性)。支持多种客户端语言(Java、Python、Go 等),与 Spring Cache、Lettuce/Jedis 集成良好。衍生工具丰富(如 RediSearch 全文检索、RedisJSON 支持 JSON 存储)。Memcached:社区活跃度低,最新稳定版停留在 1.6 系列(2020 年发布)。客户端支持较少,功能扩展依赖第三方(如 Twemproxy、McRouter)。结论:Redis 的生态更完善,适合长期维护和迭代。6. 典型使用场景对比场景MemcachedRedis简单缓存(静态数据)适用适用,但功能过剩排行榜、计数器需应用层实现直接用 Sorted Set 或 INCR实时分析、流处理不支持用 Stream 或 HyperLogLog消息队列需依赖外部工具(如 RabbitMQ)用 List 或 Pub/Sub分布式锁需用 SETNX 模拟,易出错原生支持 Redlock 算法跨数据中心同步需自行实现用 Redis Enterprise 的 Active-Active总结:为什么 Redis 更受欢迎?功能全面:支持复杂数据结构和高级功能,减少开发成本。持久化与高可用:满足生产环境对数据安全和可靠性的要求。性能足够:在简单场景下与 Memcached 差距小,复杂场景优势明显。生态完善:社区活跃,工具链成熟,易于集成和扩展。长期维护:Redis 是主流选择,Memcached 已逐渐成为遗留系统。建议:如果项目仅需简单缓存且对内存效率极度敏感(如超大缓存场景),可考虑 Memcached。其他场景(尤其是互联网高并发、分布式系统)优先选择 Redis。
  • [技术干货] spring boot 使用缓存的场景
    在 Spring Boot 中,缓存(Caching)是一种优化性能、减少重复计算和数据库查询的有效手段。以下是适合使用缓存的典型场景及注意事项:1. 适合使用缓存的场景(1) 频繁读取但较少修改的数据示例:配置信息(如系统参数、静态字典)。商品详情、用户基本信息等(读多写少的业务数据)。天气数据、汇率等第三方 API 返回的稳定结果。原因:缓存可以避免每次请求都查询数据库或调用外部服务,显著降低响应时间。(2) 计算密集型操作的结果示例:复杂的报表生成、数据分析结果。机器学习模型的推理结果(如推荐系统)。原因:缓存计算结果可以避免重复消耗 CPU 资源。(3) 热点数据(Hot Data)示例:电商首页的促销商品列表。社交媒体的热门话题或趋势。原因:热点数据访问频率极高,缓存能大幅减轻后端压力。(4) 分布式系统中的数据共享示例:多个微服务需要共享的参考数据(如国家列表、状态码)。原因:通过分布式缓存(如 Redis)避免数据不一致和重复加载。(5) 避免雪崩或穿透的中间层场景:高并发下防止数据库被击穿(如缓存空值或默认值)。工具:结合布隆过滤器(Bloom Filter)或本地缓存(如 Caffeine)。2. 不适合使用缓存的场景数据频繁更新:缓存频繁失效会导致性能下降(如实时交易数据)。数据量极大:缓存全部数据可能占用过多内存(如用户行为日志)。强一致性要求:缓存与数据库的延迟可能导致数据不一致(如金融账户余额)。一次性查询:仅执行一次的查询无需缓存。3. Spring Boot 中缓存的实现方式(1) 本地缓存(单机)工具:Caffeine(推荐):高性能的 Java 缓存库,支持过期策略和大小限制。Guava Cache:Google 的缓存库,功能类似但较旧。Ehcache:支持分布式和持久化(但通常用于本地)。配置示例(Caffeine):spring: cache: type: caffeine caffeine: spec: maximumSize=1000,expireAfterWrite=10m@Cacheable(value = "products", key = "#id") public Product getProductById(Long id) { return productRepository.findById(id).orElse(null); } (2) 分布式缓存(集群)工具:Redis:支持持久化、高可用和多种数据结构。Memcached:简单的键值存储,性能高但功能较少。配置示例(Redis):spring: cache: type: redis redis: time-to-live: 600000 # 缓存过期时间(毫秒) @Cacheable(value = "users", key = "#username") public User getUserByUsername(String username) { return userRepository.findByUsername(username); } (3) 自定义缓存通过实现 CacheManager 接口,可以集成其他缓存系统(如 Hazelcast、Apache Ignite)。4. 缓存策略与注意事项过期策略:设置合理的 TTL(Time To Live)避免数据过时。使用 @CacheEvict 手动清除缓存(如数据更新时)。@CacheEvict(value = "products", key = "#product.id") public void updateProduct(Product product) { productRepository.save(product); } 缓存穿透:缓存空值或使用布隆过滤器拦截无效请求。缓存雪崩:随机化过期时间,避免大量缓存同时失效。缓存一致性:通过消息队列(如 Kafka)通知缓存更新(最终一致性模型)。5. 总结用缓存:读多写少、计算耗时、热点数据、分布式共享。不用缓存:频繁更新、数据量大、强一致性、一次性查询。工具选择:单机应用:Caffeine。分布式系统:Redis。监控:使用 Spring Boot Actuator 或 Redis 监控缓存命中率(Hit Rate)。通过合理使用缓存,可以显著提升系统性能,但需权衡一致性、内存占用和复杂度。
  • [干货汇总] 如何解决鸿蒙多端数据高频并发写入系统时成功率低的问题
    一、业务背景我们项目中收支记录、账本数据需高频并发写入系统 。此前,用户记账操作成功率低至 70%,大量用户因记账失败、体验差而流失,严重阻碍业务发展 二、原因分析 全量数据一次性提交,超出系统承载能力当用户批量录入多条记账记录(如导入账单、批量补记)时,前端未做分批处理,直接将所有数据(可能达数百条)通过单次请求提交至后端。后果:单条请求数据量过大(如 100 条记录的 JSON 体积超过 1MB),导致网络传输超时(尤其弱网环境下);后端接口可能因 “单次请求数据量超限” 直接拒绝(如网关层设置请求体大小限制),或处理时内存占用激增,触发超时熔断未适配设备性能差异,固定逻辑引发低端机崩溃不同设备(如高端旗舰机 vs 入门级手机)的 CPU、内存、网络能力差异显著,但前端采用统一的处理逻辑缺乏操作进度反馈,用户误判失败批量记账时,前端未展示实时进度(如 “已完成 30%”),用户在等待过程中因 “无响应” 误以为操作失败:可能手动刷新页面或重复提交,导致重复请求冲突(如同一笔记录被提交两次),后端因 “数据重复” 返回失败;长时间无反馈触发用户焦虑,直接关闭页面,导致未完成的操作中断三、解决思路动态分批处理:针对全量数据一次性提交超出系统承载的问题,采用 “按需拆分、动态调整” 策略进度可视化与交互反馈:针对用户因无反馈而误判失败的问题,通过 “实时感知、明确反馈” 增强操作透明度异常处理与重试机制:针对网络波动、系统异常导致的写入失败,通过 “容错兜底、自动重试” 降低失败概率四、解决方案4.1 数据分批处理(基础分批逻辑)当用户触发大量记账数据录入操作时,利用 ArkTS 的异步任务调度能力,将数据按固定批次拆分。通过迭代数据数组,每次截取指定数量(初始 20 条)的数据作为一批,调用封装的写入方法逐批处理,避免一次性加载全量数据导致内存溢出或 UI 阻塞// 写入方法async function batchWriteAccountingData(data: AccountingDataItem[]): Promise<void> { const batchSize = 20; for (let i = 0; i < data.length; i += batchSize) { const batch = data.slice(i, i + batchSize); await writeBatchData(batch); // 异步写入,避免阻塞主线程 }}// 记账明细interface AccountingDataItem { id: string; amount: number; type: 'income' | 'expense';}4.2 动态分批调整(结合设备状态)借助鸿蒙系统提供的 hidebug 模块获取设备内存占用信息,实时判断设备内存状态。定义内存阈值(需结合实际设备测试确定),动态调整每批数据量:内存充裕时增大批次(如 30 条)以加快处理;内存紧张时减小批次(如 15 条)import { hidebug } from '@ohos.hidebug';async function getDynamicBatchSize(): Promise<number> { const memoryUsage = hidebug.getNativeHeapAllocatedSize(); // 根据实际设备性能测试调整 const lowMemoryThreshold = 1024 * 1024 * 200; // 200MB const highMemoryThreshold = 1024 * 1024 * 500; // 500MB if (memoryUsage < lowMemoryThreshold) { return 30; } else if (memoryUsage > highMemoryThreshold) { return 15; } return 20;}async function dynamicBatchWrite(data: AccountingDataItem[]): Promise<void> { const batchSize = await getDynamicBatchSize(); for (let i = 0; i < data.length; i += batchSize) { const batch = data.slice(i, i + batchSize); await writeBatchData(batch); }}4.3 进度可视化与交互反馈(UI 组件集成)在记账操作页面,使用 ArkTS 的 Progress 组件实时展示写入进度。通过计算已处理数据量与总数据量的比例,动态更新进度条数值。同时,结合 Toast 或弹窗反馈关键状态(“数据写入中”“写入完成”“网络异常重试” ),增强用户对操作流程的感知@Entry@Componentstruct AccountingWritePage { @State progressValue: number = 0; @State isWriting: boolean = false; private totalDataCount: number = 0; build() { Column() { Text('记账数据写入中') .fontSize(20) .margin({ bottom: 10 }); Progress({ value: this.progressValue, total: 100 }) .width(300) .height(20) .margin({ bottom: 20 }); if (this.isWriting) { Text(`已完成 ${this.progressValue.toFixed(1)}%`) .fontSize(14) .color(Color.Grey); } else { Button('开始写入') .onClick(async () => { this.isWriting = true; const data = await fetchAccountingData(); this.totalDataCount = data.length; await this.batchWriteWithProgress(data); this.isWriting = false; // 写入完成反馈 Toast.show({ message: '记账数据写入完成!' }); }); } } .padding(20) .width('100%') .height('100%') .justifyContent(FlexAlign.Center); } private async batchWriteWithProgress(data: AccountingDataItem[]): Promise<void> { const batchSize = await getDynamicBatchSize(); const totalBatches = Math.ceil(data.length / batchSize); let processedCount = 0; for (let i = 0; i < data.length; i += batchSize) { const batch = data.slice(i, i + batchSize); await writeBatchData(batch); processedCount += batch.length; this.progressValue = (processedCount / this.totalDataCount) * 100; // 业务逻辑 await new Promise(resolve => {}); } }}4.4 异常处理与重试机制在分批写入过程中,捕获网络请求异常、系统写入失败等错误。通过设置重试次数(如 3 次),针对失败批次自动重试;若重试仍失败,记录失败数据并反馈给用户,支持手动触发重试或跳过失败项const MAX_RETRY_COUNT = 3;async function writeBatchDataWithRetry(batch: AccountingDataItem[], retryCount: number = 0): Promise<boolean> { try { await writeBatchData(batch); // 写入 return true; } catch (error) { if (retryCount < MAX_RETRY_COUNT) { // 重试 return writeBatchDataWithRetry(batch, retryCount + 1); } else { // 记录失败数据,可存入本地缓存待后续处理 saveFailedBatch(batch); console.error('写入失败,已达最大重试次数:', error); return false; } }}// 在分批写入循环中替换为带重试的方法async function dynamicBatchWrite(data: AccountingDataItem[]): Promise<void> { const batchSize = await getDynamicBatchSize(); for (let i = 0; i < data.length; i += batchSize) { const batch = data.slice(i, i + batchSize); await writeBatchDataWithRetry(batch); }}五、方案总结本方案通过以下核心技术解决性能问题:动态分批处理技术,通过结合设备状态动态调整数据分批大小,形成一套灵活、高效的动态分批处理机制,可复用至其他需批量数据处理的业务场景,优化数据写
  • [方案分享] 如何解决鸿蒙列表滑动加载过程中会出现白块的问题
    一、业务背景在处理大量页面数据的场景下,用户进行快速查询操作时遇到了严重的性能问题:页面加载缓慢,长时间显示白屏,用户交互体验极差。经统计,该问题导致用户使用率降低了 60%,对业务发展产生了显著影响 二、原因分析2.1 数据加载策略失当,内存占用超限原始方案采用ForEach组件一次性加载全量数据(如数百甚至数千条记录),直接将所有数据存入内存并构建组件树:内存压力:大量数据对象(如每条记录包含文本、图片 URL、状态标识等)同时驻留内存,导致 JS 引擎内存占用激增(如 500 条记录可能占用 200MB + 内存),低端设备易触发内存溢出(OOM),引发页面崩溃或强制刷新。加载阻塞:全量数据请求通过单次接口调用完成,若数据量过大(如响应体超过 1MB),网络传输耗时增加(尤其弱网环境下),且接口处理时间延长,超过前端超时阈值(如 5 秒)后,用户看到的仍是 “白屏”。2.1 LazyForEach缓存配置僵化,预加载不足 若cachedCount(预加载缓存项数量)默认值为 1(系统默认),未根据列表项高度和屏幕尺寸动态调整:滑动时白屏:用户快速滑动列表时,视口外的列表项因未被缓存而销毁,滑动至新区域时需重新创建组件并加载资源(如图片),导致短暂白屏(尤其图片占比高的场景)。重复渲染损耗:缓存项不足时,列表项会在 “进入视口→离开视口→再次进入” 的过程中反复销毁与重建,浪费 CPU 资源,加剧滑动卡顿。三、解决思路数据按需精简与结构化传输,在现有懒加载、缓存优化及预加载机制的基础上,从数据源头减少传输与处理成本,进一步缓解前端性能压力,具体思路如下:通过后端接口优化,只传输前端当前场景下必需的数据字段,并采用结构化格式减少冗余信息,从根源上降低网络传输耗时、JS 内存占用及组件渲染压力四、解决方案4.1 列表优化列表页面结构比较复杂,最外层为Refresh组件包裹,第一层子组件为List组件,然后再里面有WaterFlow组件的嵌套,必须保证列表代码结构设计的比较好,不然会容易出现掉帧,卡顿,以及滑动过程中图片内容显示空白等问题。主要是从以下几个方面进行的优化处理:懒加载与缓存策略实现从官方文档可以了解到ForEach是从列表数据源一次性加载全量数据,且一次性并全部挂载在组件树上;LazyForEach是按需加载部分数据,只构建出一棵短小的组件树。针对数据加载和组件树构建这两个显著差异。另外我们还需要知道的是List等组件中cachedCount属性默认为1,所以当使用LazyForEach没有设置缓存项数量的时候,默认的缓存项数量实际为1懒加载代码的实现:import { ObservedArray, Observed } from '@ohos.data.observed';import { IDataSource, DataChangeListener } from '@ohos.app.ability.dataSource';const TAG = '[AdvancedLazyDataSource]';/** * 基础数据源接口实现 * 提供数据变更通知机制 */class BasicDataSource<T> implements IDataSource { private listeners: DataChangeListener[] = []; public totalCount(): number { return 0; } public getData(_index: number): T | undefined { return undefined; } registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { this.listeners.push(listener); } } unregisterDataChangeListener(listener: DataChangeListener): void { const pos = this.listeners.indexOf(listener); if (pos >= 0) { this.listeners.splice(pos, 1); } } // 批量数据变更通知 notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); }); } // 单项数据添加通知 notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); }); } // ...}/** * 高级懒加载数据源实现 * 增加了数据分批加载、虚拟滚动支持等功能 */@Observedexport default class AdvancedLazyDataSource<T> extends BasicDataSource<T> { @State dataArray: T[] = []; private pageSize: number = 20; // 每页加载数量 private totalPages: number = 0; // 总页数 private currentPage: number = 1; // 当前页码 private isLoading: boolean = false; // 加载状态 /** * 获取数据总数 */ public totalCount(): number { return this.dataArray.length; } /** * 获取指定位置数据 */ public getData(index: number): T { return this.dataArray[index]; } /** * 添加数据到指定位置 */ public addData(index: number, data: T): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(index); } /** * 追加数据到末尾 */ public pushData(data: T): void { this.dataArray.push(data); this.notifyDataAdd(this.dataArray.length - 1); } /** * 加载更多数据 * @param page 页码 * @returns 加载结果 */ public async loadMoreData(page: number = this.currentPage + 1): Promise<boolean> { if (this.isLoading || page > this.totalPages) { return false; } this.isLoading = true; try { // 模拟网络请求加载数据 const newData = await this.fetchDataFromServer(page, this.pageSize); // 更新数据源 const startIndex = this.dataArray.length; this.dataArray.push(...newData); // 通知数据变更 for (let i = 0; i < newData.length; i++) { this.notifyDataAdd(startIndex + i); } this.currentPage = page; return true; } catch (error) { console.error(TAG, 'Load more data failed', error); return false; } finally { this.isLoading = false; } } /** * 从服务器获取数据 * @param page 页码 * @param size 每页数量 * @returns 数据数组 */ private async fetchDataFromServer(page: number, size: number): Promise<T[]> { // 实际项目中这里应该是网络请求 // 模拟延迟 await new Promise(resolve => setTimeout(resolve, 300)); // 模拟数据 return Array.from({ length: size }, (_, i) => ({ id: `${page}-${i}`, content: `Item ${page * size + i}` }) as unknown as T); } /** * 重置数据源 */ public reset(): void { this.dataArray = []; this.currentPage = 1; this.isLoading = false; this.notifyDataReload(); }}缓存策略优化LazyForEach 组件的缓存策略对性能影响显著:cachedCount 属性:指定预加载的缓存项数量,默认为 1优化策略:对于一般列表:设置 cachedCount 为 5-10,平衡首屏加载速度和滑动体验对于长列表:根据列表项高度和屏幕高度动态计算 cachedCount对于快速滑动场景:可适当增大 cachedCount,但需测试首屏加载时间4.2 动态预加载(Prefetcher 机制)     HarmonyOS 提供的 Prefetcher 机制具有以下特点动态自适应:根据网络状态智能调整预加载策略按需预取:只预加载视口附近的数据和资源资源缓存:将预加载的资源缓存到本地,减少重复请求请求管理:自动管理预加载请求,避免资源浪费预加载流程:用户滑动列表 → 计算可见区域 → 触发visibleAreaChanged → Prefetcher预取可见区域附近数据 → 缓存资源 → 列表项需要时直接使用缓存资源预加载与懒加载的协同工作:懒加载:解决大数据量下的组件渲染性能问题预加载:解决资源加载延迟导致的白屏问题组合使用:实现 "即见即得" 的流畅体验预加载实现细节创建IDataSourcePrefetching接口的实现类export class CardDataSource implements IDataSourcePrefetching { private dataList: Array<V11BaseCardShowModel> = []; private listeners: DataChangeListener[] = []; private readonly requestsInFlight: HashMap<number, rcp.Request> = new HashMap(); private readonly session: rcp.Session = rcp.createSession(); private readonly cachePath = getContext().getApplicationContext().cacheDir; constructor(showModelList: Array<ShowModel>) { this.dataList = showModelList; } async prefetch(index: number): Promise<void> { const item = this.dataList[index]; if (this.requestsInFlight.hasKey(index)) { return; } if (item.cachedImage != "") { return; } const request = new rcp.Request(item.thumbnail.imageUrl, 'GET'); this.requestsInFlight.set(index, request); try { //提前拉取数据 const response = await this.session.fetch(request); if (response.statusCode !== 200 || !response.body) { Logger.error('CardDataSource response code:' + response.statusCode); return } // 将加载的数据信息存储到缓存文件中 item.cachedImage = await this.cacheImg(item.id, response.body); // 删除指定元素 this.requestsInFlight.remove(index); } catch (err) { if (err.code !== CANCEL_CODE) { //失败就直接使用url链接 item.cachedImage = item.thumbnail.imageUrl; // 移除有异常的网络请求任务 this.requestsInFlight.remove(index); } } }}创建实际使用的IDataSourcePrefetching的实现对象和BasicPrefetcher对象// 创建DataSourcePrefetching对象,具备任务预取、取消能力的数据源@State dataSource: CardDataSource = new CardDataSource(new Array<ShowModel>())private readonly prefetcher = new BasicPrefetcher(this.dataSource);数据刷新时,要立刻刷新BasicPrefetcher中DataSource // LazyForEach的数据源更新 this.dataSource.updateData(showModels) this.prefetcher.setDataSource(this.dataSource); 调用BasicPrefetcher的visibleAreaChanged方法.onScrollIndex((start: number, end: number) => { this.prefetcher.visibleAreaChanged(start, end) })  五、方案总结本方案通过以下核心技术解决性能问题:懒加载技术:使用 LazyForEach 避免一次性加载全量数据缓存策略:优化 cachedCount 参数减少滑动延迟预加载机制:利用 Prefetcher 提前加载资源减少白屏组件优化:简化结构减少渲染开销网络优化:根据网络状态动态调整加载策略
  • [问题求助] 鲲鹏920的服务器BIOS设置里面的Cache Mode和 Stream Write Mode有介绍吗?
    现在我需要对LLC进行调优,发现BIOS里面有这些地方涉及LLC但是不知道Cache Moded和Stream Write Mode的各个选项的区别在哪里https://bbs.huaweicloud.com/forum/thread-102569-1-1.html这个帖子里有人回答了第一个问题,但是链接失效了.希望有大佬解惑!
  • [技术干货] 本地缓存与redis缓存的不同
    本地缓存与redis缓存的不同  本地缓存和Redis缓存都是常见的缓存方案,它们在实现方式、使用场景等方面有所不同:  1:实现方式:本地缓存通常指内存中的缓存,它将数据存储在应用程序的进程空间中,读取速度非常快。而Redis缓存则是一种网络缓存,通过将数据存储在远程服务器上,使得多个应用程序可以共享同一份缓存数据。  2:数据持久化:本地缓存通常并不需要将数据持久化到硬盘上,因此在重启应用程序后,缓存数据会丢失;而Redis缓存提供了持久化功能,可以将缓存数据保存到磁盘上,即使重启Redis服务,也能够恢复之前缓存的数据。  3:使用场景:本地缓存适合于对数据访问频繁的场景,例如应用程序中某些数据的查询、计算等操作。而Redis缓存则更适合于分布式环境下的应用程序,以及需要共享缓存数据的多个应用程序之间。  4:高可用性:为了确保高可用性,Redis提供了哨兵(sentinel)和集群(cluster)两种解决方案,可以自动完成故障转移,保证系统的稳定性。而本地缓存没有这种高可用性保障措施,需要应用程序自己实现。  redis和应用服务装在同一个服务器上,为什么不用本地缓存而使用redis缓存? 完全可以在Redis和应用服务安装在同一台服务器上的情况下使用本地缓存。实际上,有些应用场景中,使用本地缓存可能比Redis缓存更为合适。 但是,使用Redis缓存也有一些优势。例如: 1:支持多种数据结构:Redis支持多种常见的数据结构,如字符串、哈希表、列表等,而本地缓存只支持基本的键值对结构。 2:可以作为分布式缓存方案:当多个应用服务部署在不同的服务器上时,通过Redis缓存共享数据可以更加方便和高效。 3:支持一些高级功能:例如通过事务管理和Publish/Subscribe机制实现更多的功能。 4:稳定性和可靠性高:Redis提供了很多调试和监控工具来保障服务稳定运行,避免数据丢失和宕机等问题。 
  • [技术干货] 查询缓存
    当一个SQL执行时首先会进入查询缓存查看之前是否执行过该语句,如果执行过则会以key-value的形式保存在缓存中,key是查询语句,value是查询结果如果缓存命中则直接返回结果,如果查询语句不在缓存中继续后面的流程大多数情况下我们不推荐使用查询缓存,因为缓存失效非常频繁,只要一个更新,那么这个表上所有的缓存都会失效,吐过数据的更新比较多,那么缓冲命中的效率很低,不断的在失效在MySQL中提供了参数 query_cache_type 参数来设置,默认是 DEMAND ,表示对默认的SQL都不使用查询缓存,如果要对特的语句进行缓存查询,则可以使用 SQL_CACHE 来显示的指定
  • [技术干货] 缓存雪崩怎么办
    a、在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。(跟击穿的第一个方案类似,但是这样是避免不了其它key去查数据库,只能减少查询的次数)b、可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存    不同的key,设置不同的过期时间,具体值可以根据业务决定,让缓存失效的时间点尽量均匀c、做二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。(这种方式复杂点)
  • [技术干货] 缓存击穿
    缓存击穿中的热点key在数据库中是存在的,在缓存中也存在过,只是在这些热点数据失效的瞬间,发起了大量对热点数据的请求,导致缓存中不命中直接访问数据库,造成对数据库的巨大压力
  • [技术干货] 缓存击穿
    与缓存穿透不同,缓存击穿中的热点key在数据库中是存在的,在缓存中也存在过,只是在这些热点数据失效的瞬间,发起了大量对热点数据的请求,导致缓存中不命中直接访问数据库,造成对数据库的巨大压力
  • 1元云缓存新手礼,助力企业新气象!
    本帖最后由 云彩飞扬 于 2018-3-28 10:27 编辑每逢节日电商平台为了吸引用户和流量,经常会做促销活动,以及限时抢购,各种促销活动有增无减,这也引得了越来越多的用户来争相购买。在巨大成交量的背后,暴增的用户和流量的冲击,使得网站访问卡顿,将会给网民体验带来巨大的影响。因为用户体验不好,用户将会选择体验好的商家去进行购买活动,流失的用户给电商企业造成了巨大的经济损失。什么是用户体验?用户体验是指用户对性能的体验,一般包括(响应时间,延迟时间,吞吐量,并发用户数和资源利用率)用户体验与缓存有什么关系?缓存是最小化系统工作,使用了缓存就不用反复的从数据中查找,这样从浏览器到网络,到服务器里访问数据库,可以降低系统响应时间,减少网络传输时间和应用延迟时间,进而提高了系统的吞吐量,增加了系统的并发用户数,更好的利用了系统的资源。 大部分商家网站遇到巨大的流量和高频率的请求时,每次数据库查询耗费的时间将会非常久,这也是网站卡顿的首要因素。而华为云云缓存Redis可以将静态资源(如:活动页面,用户信息,热销商品展示、秒杀推荐等数据等),提前的存储在数据库缓存当中,方便用户就近读取所需内容,降低网络堵塞,提高用户访问响应速度,用户体验得到大幅度提升。在活动时候,网站的访问量没办法估计的。使用云缓存Redis,企业可按照自身的需求,通过Web界面的实例管理,一键式完成实例扩容,集群、主备实例扩容,期间不影响上层业务,满足秒杀场景下的访问量增长。大大降低后端服务器的渲染,数据库的访问,保证网站稳定快速运行。云缓存Redis隆重推出1元新手礼致力于为客户提供开箱即用、高性能、高可靠、高安全、易扩展的内存数据库服务现开现用,立省数千元。重要的事情说三遍仅需1元,畅享30天!仅需1元,高效安全更稳定!仅需1元,助力企业新气象!数量有限,先到先得!快来领取吧!
  • 【搞事情】1元云缓存新手礼超值体验,错过等一年!!!
    本帖最后由 中间件小哥 于 2018-3-13 12:59 编辑亲爱的伙伴们深圳的天气蹭蹭的持续上升没错春天来了!暖暖的春风是不是很沉醉呀!11936这个春天过的是不是很有夏天的感觉呀!伙伴们不要觉得惊讶!反复变化的天气才是深圳最正确的打开方式! 不信,你看 11948 昨天女神节,温度直跌10度 11950闺蜜抱怨:好不容易的半天假期有一男神约我吃火锅搞不好是想追我却因为说变就变的天气直接拒绝了,后悔ing呆在家里无法自拔于是拿起了手机,逛起了某宝。告诉我哪个平台的限时抢购优惠力度最大! 我说:还有比我们云缓存Redis 1元新手礼更优惠的? 11951闺蜜说:我只是买衣服,买化妆品,你跟我说啥我听不懂!看来抢购才是女孩子的真爱啊! 难怪电商平台每逢节日做促销活动,以及限时抢购,各种促销活动有增无减 那么问题来了在暴增的用户和流量的冲击下怎么才让用户的访问畅通无阻呢? 致胜法宝 大部分商家网站遇到巨大的流量和高频率的请求时,每次数据库查询耗费的时间将会非常久,这也是网站卡顿的首要因素。而华为云云缓存Redis可以将静态资源(如:活动页面,用户信息,热销商品展示、秒杀推荐等数据等),提前的存储在数据库缓存当中,方便用户就近读取所需内容,降低网络堵塞,提高用户访问响应速度,用户体验得到大幅度提升。在活动时候,网站的访问量没办法估计的。使用云缓存Redis,企业可按照自身的需求,通过Web界面的实例管理,一键式完成实例扩容,集群、主备实例扩容,期间不影响上层业务,满足秒杀场景下的访问量增长。大大降低后端服务器的渲染,数据库的访问,保证网站稳定快速运行。云缓存Redis隆重推出1元新手礼致力于为客户提供开箱即用、高性能、高可靠、高安全、易扩展的内存数据库服务现开现用,立省数千元。重要的事情说三遍仅需1元,畅享30天!仅需1元,高效安全更稳定!仅需1元,助力企业新气象!数量有限,先到先得!快来领取吧!
  • 如何删除缓存实例?
    本帖最后由 云彩飞扬 于 2018-2-6 15:08 编辑操作场景分布式缓存服务管理控制台支持删除缓存实例,且可实现批量删除缓存实例、一键式删除创建失败的缓存实例。警告:缓存实例删除后,实例中原有的数据将被删除,且没有备份,请谨慎操作。前提条件[*]缓存实例已存在。 [*]缓存实例状态为运行中、故障、已关闭时才能执行删除操作。操作步骤删除缓存实例[*]登录管理控制台。 [*]单击“数据库 > 分布式缓存服务”,进入分布式缓存服务信息页面。 [*]单击左侧菜单栏的“缓存管理”。 [*]勾选“名称”栏下的需要删除的缓存实例左侧的方框,可选一个或多个。 缓存实例状态为创建中、启动中、停止中、重启中时不允许执行删除操作。 [*]单击信息栏左上侧的“删除”。 [*]单击“确定”,完成删除缓存实例。 删除缓存实例大约需要1到30分钟。 说明:如果只需要删除单个缓存实例,也可以在“缓存管理”界面,单击需要删除的缓存实例右侧“操作”栏下的“更多 > 删除”。
  • 如何重启缓存实例?
    本帖最后由 云彩飞扬 于 2018-1-31 16:49 编辑操作场景分布式缓存服务管理控制台支持重启运行中的缓存实例,且可实现批量重启缓存实例。前提条件只有当缓存实例处于“运行中”或“故障”状态,才能执行此操作。操作步骤1.登录管理控制台。单击“数据库 > 分布式缓存服务”,进入分布式缓存服务信息页面。单击左侧菜单栏的“缓存管理”。2.勾选“名称”栏下的相应缓存实例名称左侧的方框,可选一个或多个。3.单击信息栏左上侧的“重启”。4.单击“确定”,完成重启缓存实例。5.重启缓存实例大约需要1到30分钟。缓存实例重启成功后,缓存实例状态切换为“运行中”。警告:缓存实例重启后,单机实例中原有的数据将被删除。在缓存实例重启过程中,用户无法对实例进行读写操作。在缓存实例重启过程中,如果有正在进行的备份操作,可能会重启失败。说明: 如果重启单个实例,也可以在需要重启的缓存实例右侧,单击“操作”栏下的“更多 > 重启”。
  • 如何开启缓存实例?
    操作场景分布式缓存服务管理控制台支持开启已关闭的缓存实例,且可实现批量开启缓存实例。前提条件只有当缓存实例处于“已关闭”状态,才能执行此操作。操作步骤[*]登录管理控制台。 [*]单击“数据库 > 分布式缓存服务”,进入分布式缓存服务信息页面。 [*]单击左侧菜单栏的“缓存管理”。 [*]勾选“名称”栏下的相应缓存实例名称左侧的方框,可选一个或多个。 [*]单击信息栏左上侧的“开启”。 [*]单击“确定”,完成开启缓存实例。 [*]开启缓存实例大约需要1到30分钟。 [*]缓存实例开启成功后,实例状态从“已关闭”切换为“运行中”。 说明:如果开启单个实例,也可以在需要开启的缓存实例右侧,单击“操作”栏下的“开启”。