关于redis:Redis-实战-03-Redis-简单实践-Web应用

需要性能: P23登录 cookie购物车 cookie缓存生成的网页缓存数据库行剖析网页拜访记录高层次角度下的 Web 利用 P23从高层次的角度来看, Web 利用就是通过 HTTP 协定对网页浏览器发送的申请进行响应的服务器或者服务(service)。 Web 申请个别是无状态的(stateless),即服务器自身不会记录与过往申请无关的任何信息,使得生效的服务器能够很容易地被替换掉。 Web 服务器对申请进行响应的典型步骤: 服务器对客户端发来对申请(request)进行解析申请被转发给一个预约义的处理器(handler)处理器可能会从数据库中取数据处理器依据数据对模板(templete)进行渲染(render)处理器向客户端返回渲染后的内容作为对申请的响应(response)根底数值量 P24本次实际所有内容均围绕着发现并解决一个虚构的大型网上商店来开展的,一些根底数据量如下: 每天有 500 万名不同的用户每天有 1 亿次点击每天从网站购买超过 10 万件商品实现登录和 cookie 缓存 P24有两种常见的办法能够将登录信息存储在 cookie 外面: 签名(signed) cookie:通常会存储用户名,可能还会有其余网站感觉游泳的信息,例如:最初一次胜利登录工夫、用户 id 等。还会有签名,用服务器验证 cookie 中的信息是否被批改。令牌(token) cookie:存储遗传随机字节作为令牌,服务器依据令牌在数据库中查找令牌的领有着。随着工夫的推移,旧令牌会被新令牌取代。签名 cookie 和令牌 cookie 的长处与毛病 P24cookie 类型长处毛病签名 cookie验证 cookie 所需的所有信息都存储在 cookie 外面。cookie 能够蕴含额定的信息,并且对这些信息进行签名也很容易正确地解决签名很难。很容易遗记对数据进行签名,或者遗记验证数据的签名,从而造成安全漏洞令牌 cookie增加信息非常容易。 cookie 的体积十分小,因而挪动终端和速度较慢的客户端能够更快地发送申请须要在服务器存储更多信息。如果应用的是关系数据库,那么载入和存储 cookie 的代价可能会很高本次实际采纳令牌 cookie 来援用存储的用户登录信息的条目。除登录信息外,还须要将用户拜访时长和已浏览商品的数量等信息存储到数据库外面,便于将来通过剖析这些信息来学习如何更好地向用户采购商品。 应用一个哈希表来存储登录 cookie 令牌与已登录用户之间的映射,依据给定的令牌查找对应的用户 id。 P24 // redis keytype RedisKey stringconst ( // 登录用户 哈希表(field:token;value:userId) LOGIN_USER RedisKey = "loginUser" // 用户最近操作工夫 有序汇合 USER_LATEST_ACTION RedisKey = "userLatestAction" // 用户最近浏览商品工夫 有序汇合 前缀(存储 itemId 及浏览的工夫戳) VIEWED_ITEM_PREFIX RedisKey = "viewedItem:" // 用户购物车 哈希表 前缀(存储 itemId 及其加车数量) CART_PREFIX RedisKey = "cart:" // 申请返回值缓存 字符串 前缀(存储 申请对应返回值的 序列化串) REQUEST_PREFIX RedisKey = "request:" // 缓存数据距离(单位:ms) 字符串 ITEM_INTERVAL RedisKey = "itemInterval" // 数据缓存工夫(准确到毫秒) 有序汇合 ITEM_CACHED_TIME RedisKey = "itemCachedTime" // 数据(商品)的json 字符串 前缀(存储 itemId 的相干信息) ITEM_PREFIX RedisKey = "item:" // 商品浏览次数 有序汇合(存储 itemId 及浏览次数) ITEM_VIEWED_NUM RedisKey = "itemViewedNum")// 依据 token 获取 userId(err 不为 nil 时,用户已登录且 userId 无效)func GetUserId(conn redis.Conn, token string) (userId int, err error) { return redis.Int(conn.Do("HGET", LOGIN_USER, token))}此时咱们曾经能通过 token 获取用户 id 了,还须要相应的设置办法,即用户每次操作时都会进行相干信息设置,并更新 token 的最近操作工夫戳。如果用户正在浏览一个商品,则还须要将该商品增加到浏览商品历史有序汇合中,且限度一个用户最多记录最新的 25 个商品浏览记录。 P25 ...

January 22, 2021 · 6 min · jiezi

关于redis:得物技术分享Redis60-新特性分析

前言为了晋升执行命令前后的网络I/O性能,Redis6.0引入了Threaded I/O。 上面就来一起学习一下新个性Threaded I/O。 本文浏览程序Redis是如何运行的命令执行前后产生了什么Threaded I/O 模型Threaded I/O 的实现于机制总结与思考Redis源码学习思路Redis是如何运行的循环处理事件Redis的函数入口在server.c中,main()办法流程如下图所示 在main()办法中Redis首先须要做的是初始化各种库以及服务配置。具体举例: crc64_init()会初始化一个crc校验用的Lookup TablegetRandomBytes()为hashseed填充随机元素作为初始化值,用作哈希表的seed…initServerConfig()中执行了大量对server对象属性的初始化操作:初始化server.runid,如29e05f486b8d41e68234a68c8b77edaff101c194获取以后的时区信息,寄存至server.timezone中初始化server.next_client_id值,使得连贯进来的客户端id从1开始自增…ACLInit()是对Redis 6.0新增的ACL零碎的初始化操作,包含初始化用户列表、ACL日志、默认用户等信息通过moduleInitModulesSystem()和tlsInit()初始化模块零碎和SSL等…初始化完结后,开始读取用户的启动参数,和大多数配置加载过程相似,Redis也通过字符串匹配等剖析用户输出的argc和argv[],这个过程中可能会产生: 获取到配置文件门路,批改server.configfile的值,后续用于加载配置文件获取到启动选项参数,如loadmodule和对应的Module文件门路,保留至options变量中解析完参数之后,执行loadServerConfig(),读取配置文件并与命令行参数options的内容进行合并,组成一个config变量,并且一一将name和value设置进configs列表中。对于每个config,有对应的switch-case的代码。 例如对于loadmodule,会执行queueLoadModule()办法,以实现真正的配置加载: ... } else if (!strcasecmp(argv[0],"logfile") && argc == 2) { ... } else if (!strcasecmp(argv[0],"loadmodule") && argc >= 2) { queueLoadModule(argv[1],&argv[2],argc-2); } else if (!strcasecmp(argv[0],"sentinel")) {...回到main办法的流程,Redis会开始打印启动的日志,执行initServer()办法,服务依据配置项,持续为server对象初始化内容,例如: 创立事件循环构造体aeEventLoop(定义在ae.h),赋值给server.el依据配置的db数目,调配大小为sizeof(redisDb) * dbnum的内存空间,server.db保留这块空间的地址指针每个db都是一个redisDb构造,将这个构造中的保留key、保留过期工夫等的字典初始化为空dict…尔后就是一些依据不同运行模式的初始化,例如惯例模式运行时会记录惯例日志、加载磁盘长久化的数据;而在sentinel模式运行时记录哨兵日志,不加载数据等。 在所有筹备操作都实现后,Redis开始陷入aeMain()的事件循环,在这个循环中会一直执行aeProcessEvents()解决产生的各种事件,直到Redis完结退出。 事件类型Redis中存在有两种类型的事件: 工夫事件文件事件工夫事件也就是到了肯定工夫会产生的事件,在Redis中它们被记录成一个链表,每次创立新的事件事件的时候,都会在链表头部插入一个aeTimeEvent节点(头插法),其中保留了该事件会在何时产生,须要调用什么样的办法解决。 遍历整个链表咱们能够晓得离最近要产生的工夫事件还有多久,因为链表外面的节点依照自增id顺序排列,而在产生工夫的维度上时乱序的。 文件事件能够看作I/O引起的事件,客户端发送命令会让服务端产生一个读I/O,对应一个读事件;同样当客户端期待服务端音讯的时候须要变得可写,让服务端写入内容,因而会对应一个写事件。AE_READABLE事件会在客户端建设连贯、发送命令或其余连贯变得可读的时候产生,而AE_WRITABLE事件则会在客户端连贯变得可写的时候产生。 文件事件的构造简略很多,aeFileEvent记录了这是一个可读事件还是可写事件,对应的解决办法,以及用户数据。 /* File event structure */typedef struct aeFileEvent { int mask; /* one of AE_(READABLE|WRITABLE|BARRIER) */ aeFileProc *rfileProc; /* 读事件处理办法 */ aeFileProc *wfileProc; /* 写事件处理办法 */ void *clientData;} aeFileEvent;如果同时产生了两种事件,Redis会优先解决AE_READABLE事件。 ...

January 22, 2021 · 8 min · jiezi

关于redis:Redis-实战-02-Redis-简单实践-文章投票

需要性能: P15公布文章获取文章文章分组投反对票数值及限度条件 P15如果一篇文章取得了至多 200 张反对票,那么这篇文章就是一篇乏味的文章如果这个网站每天有 50 篇乏味的文章,那么网站要把这 50 篇文章放到文章列表页前 100 位至多一天反对文章评分(投反对票会加评分),且评分随工夫递加实现投反对票 P15如果要实现评分实时随工夫递加,且反对按评分排序,那么工作量很大而且不准确。能够想到只有工夫戳会随工夫实时变动,如果咱们把公布文章的工夫戳当作初始评分,那么后公布的文章初始评分肯定会更高,从另一个层面上实现了评分随工夫递加。依照每个乏味文章每天 200 张反对票计算,均匀到一天(86400 秒)中,每张票能够将分进步 432 分。 为了依照评分和工夫排序获取文章,须要文章 id 及相应信息存在两个有序汇合中,别离为:postTime 和 score 。 为了避免对立用户对对立文章屡次投票,须要记录每篇文章投票的用户id,存储在汇合中,为:votedUser:{articleId} 。 同时规定一篇文章公布期满一周后不能再进行投票,评分将被固定下来,同时记录文章曾经投票的用户名单汇合也会被删除。 // redis keytype RedisKey stringconst ( // 公布工夫 有序汇合 POST_TIME RedisKey = "postTime" // 文章评分 有序汇合 SCORE RedisKey = "score" // 文章投票用户汇合前缀 VOTED_USER_PREFIX RedisKey = "votedUser:" // 公布文章数 字符串 ARTICLE_COUNT RedisKey = "articleCount" // 公布文章哈希表前缀 ARTICLE_PREFIX RedisKey = "article:" // 分组前缀 GROUP_PREFIX RedisKey = "group:")const ONE_WEEK_SECONDS = int64(7 * 24 * 60 * 60)const UPVOTE_SCORE = 432// 用户 userId 给文章 articleId 投赞成票(没有事务管制,第 4 章会介绍 Redis 事务)func UpvoteArticle(conn redis.Conn, userId int, articleId int) { // 计算以后工夫能投票的文章的最早公布工夫 earliestPostTime := time.Now().Unix() - ONE_WEEK_SECONDS // 获取 以后文章 的公布工夫 postTime, err := redis.Int64(conn.Do("ZSCORE", POST_TIME, articleId)) // 获取谬误 或 文章 articleId 的投票截止工夫已过,则返回 if err != nil || postTime < earliestPostTime { return } // 以后文章能够投票,则进行投票操作 votedUserKey := VOTED_USER_PREFIX + RedisKey(strconv.Itoa(articleId)) addedNum, err := redis.Int(conn.Do("SADD", votedUserKey, userId)) // 增加谬误 或 以后已投过票,则返回 if err != nil || addedNum == 0 { return } // 用户已胜利增加到以后文章的投票汇合中,则减少 以后文章 得分 _, err = conn.Do("ZINCRBY", SCORE, UPVOTE_SCORE, articleId) // 自增谬误,则返回 if err != nil { return } // 减少 以后文章 反对票数 articleKey := ARTICLE_PREFIX + RedisKey(strconv.Itoa(articleId)) _, err = conn.Do("HINCRBY", articleKey, 1) // 自增谬误,则返回 if err != nil { return }}公布文章 P17能够应用 INCR 命令为每个文章生成一个自增惟一 id 。 ...

January 21, 2021 · 6 min · jiezi

关于redis:突破开源Redis的内存限制存算分离的GaussDB到底有多能装

摘要:GaussDB(for Redis)(下文简称高斯Redis)是华为云数据库团队自主研发的兼容Redis协定的云原生数据库,该数据库采纳计算存储拆散架构,冲破开源Redis的内存限度,可轻松扩大至PB级存储。GaussDB(for Redis)(下文简称高斯Redis)是华为云数据库团队自主研发的兼容Redis协定的云原生数据库,该数据库采纳计算存储拆散架构,冲破开源Redis的内存限度,可轻松扩大至PB级存储。 本文将从存储架构、四大个性、竞争力、利用场景等方面进行介绍。 存储架构高斯Redis基于计算存储拆散架构,计算层实现热数据缓存,存储层实现全量数据的落盘,两头通过RDMA高速网络互连,通过算法预测用户的拜访法则,实现数据的主动冷热替换,最终达到极致的性能晋升。 四大个性 该架构基于华为外部弱小且宽泛应用的自研分布式存储系统DFV,实现了一套Share Everything的云原生架构,充分发挥了云原生的弹性伸缩、资源共享的劣势,使得高斯Redis具备强统一、秒扩容、低成本、超可用的四大特点,完满避开了开源Redis的主从沉积、主从不统一、fork抖动、内存利用率只有50%、大key阻塞、gossip集群治理等问题。 Ø 强统一 数据复制是存储的事件,因而业余的事件交给业余的团队来做。通过分布式存储DFV,高斯Redis轻松实现了3正本强统一,并可轻松反对6正本,为业界独创。 在强统一架构下,用户再也不必放心开源Redis的主从沉积,带来的丢数据、不统一、OOM等极其问题,更不必放心业务出错,比方计数器、限流器、拜访统计、hash字段等不统一。 Ø 秒扩容 数据规模收缩之后,扩容是个高危且艰难的操作。高斯Redis基于云原生架构,将扩容分成计算层和存储层。计算层扩容,无需任何数据搬迁,只需批改路由映射,即可秒级实现。存储层是个共建的超级数据湖,其容量微小,而且扩容是切成细腻度的64MB数据分区,对下层数据库业务简直无感。 因而高斯Redis能够轻松撑持业务的大规模收缩,并且真正做到计算/存储分层的按需扩容和购买。 Ø 低成本 高斯Redis绝对于开源Redis,在存储介质上应用了磁盘代替内存。一方面,因为采纳存算拆散架构,计算资源少了一半,即没有从节点;另一方面,存储资源按需购买,无任何节约,并且采纳了逻辑/物理压缩。最终,每GB综合老本不到开源Redis的十分之一。 Ø 超可用 开源Redis或友商Redis不论单分片还是集群,其数据复制都采纳主从架构,导致N个节点的集群,如果同时挂掉一对主从(即2个节点),整个集群就不可用。而高斯Redis采纳存算拆散之后,每个计算节点都能够看到并共享所有数据,因而N个节点,最多能够容忍挂掉N-1个节点,真正做到比高可用还高的可用性。 竞争力剖析 场景举荐高斯Redis不仅性能迫近缓存,而且其存储能力(扩展性、高性能、易用性)超过数据库。因而除了缓存场景能够抉择高斯Redis以外,上至PB级别大规模数据存储都能够抉择高斯Redis。场景参考如下: 抉择倡议 命令兼容兼容5.0协定,包含string/hast/list/zset/set/stream/geo/ HyperLogLog/bitmap/pubsub等等,但出于性能和安全性思考,禁用个别危险命令,具体参考:https://support.huaweicloud.com/usermanual-nosql/nosql_09_0076.html 容量参考以往用户抉择开源Redis的时候,须要购买内存,比方用户数据是100G,因为开源Redis内存使用率减半,须要购买200G内存,并且为了高可用,还得购买200G的从节点,那么加起来就是400G的内存。然而购买高斯Redis时,用户只须要依据实在寄存的数据大小,按需抉择购买存储空间即可,内存只是为了性能减速(内存/磁盘比越大,性能越好)。 附:材料参考 《华为云GaussDB(for Redis)与自建开源Redis的老本比照》https://www.modb.pro/db/42739 《一场由fork引发的超时,让咱们从新探讨了Redis的抖动问题》https://bbs.huaweicloud.com/blogs/227525《当Redis遇见计算存储拆散》https://developer.huaweicloud.com/hero/forum/thread-83188-1-1.html 《GaussDB(for Redis)与原生Redis的性能比照》https://bbs.huaweicloud.com/blogs/236949

January 21, 2021 · 1 min · jiezi

关于redis:redis淘汰策略原理周期删除

基于redis5.0入口redis周期删除过期数据的函数是activeExpireCycle,有两个中央调用这个函数: beforeSleep:redis在阻塞期待文件事件之前,即过程阻塞之前,会调用beforeSleep函数,清理过期数据的模式是ACTIVE_EXPIRE_CYCLE_FAST,疾速清理,不影响主流程。// server.c/* This function gets called every time Redis is entering the * main loop of the event driven library, that is, before to sleep * for ready file descriptors. */void beforeSleep(struct aeEventLoop *eventLoop) { …… /* Run a fast expire cycle (the called function will return * ASAP if a fast cycle is not needed). */ if (server.active_expire_enabled && server.masterhost == NULL) activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST); ……} databasesCron:redis周期工作,清理过期数据的模式是ACTIVE_EXPIRE_CYCLE_SLOW,绝对ACTIVE_EXPIRE_CYCLE_FAST执行工夫略微长点。// server.cvoid databasesCron(void) { /* Expire keys by random sampling. Not required for slaves * as master will synthesize DELs for us. */ if (server.active_expire_enabled) { if (server.masterhost == NULL) { activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW); } else { expireSlaveKeys(); } } ……} 以后节点为master时,server.masterhost == NULL,才执行activeExpireCycle函数。 ...

January 20, 2021 · 6 min · jiezi

关于SegmentFault:⭐Redis-备忘录-基础

[TOC] 文档/链接Redis 中文文档 如同只到 3.* 版本Redis 丑但更新的中文文档 图片来自: https://segmentfault.com/a/11...高性能官网数据: 10W+ QPS 数据存储在内存单线程: 防止上下文切换和锁多路I/O复用数据类型及利用场景String 字符串单个 String 最大可存储 512 MB二进制平安.外部实现采纳 SDS(Simple Dynamic String) 相似 Go 的切片, 通过额定调配空间防止频繁内存调配.应用场景 简略的 K-V 缓存性能计数器共享用户 Session分布式锁 联合 lua限速器 联合 lua并发控制器 联合 lua比方管制热点行更新之类的, 可参考 Laravel 6.x 的 Illuminate\Redis\Limiters\ConcurrencyLimiter Set 汇合无序汇合, 主动去重反对交加, 并集, 差集操作应用场景 排重独特XX(独特好友....)ZSet 有序汇合应用场景 Top N 排行榜 复合排序List 列表应用场景 New Top N音讯队列 lpush, rbpop Laravel的异步队列 Listqueues:default 期待执行的队列工作, rpush 和 lpopSorted Set queues:default:delayed 提早工作队列(包含失败重试)Sorted Set queue:default:reserved 保留工作队列(执行中的队列, 防止脚本解体)取工作: ...

January 20, 2021 · 6 min · jiezi

关于redis:灵活且不失高性能这个-POSIX-共享文件系统值得一用

项目名称: JuiceFS 我的项目作者: Juicedata 开源许可协定: AGPL-3.0 我的项目地址:https://gitee.com/juicedata/JuiceFS 我的项目简介JuiceFS 是一个建设在 Redis 和 S3 等对象存储之上的开源 POSIX 文件系统。它是为云原生环境设计,通过把元数据和数据别离长久化到 Redis 和对象存储中,它相当于一个无状态的中间件,帮忙各种利用通过规范的文件系统接口来共享数据。 我的项目个性残缺 POSIX 兼容:已有利用能够无缝对接;极致的性能:毫秒级的提早,近乎有限的吞吐量(取决于对象存储规模);云原生:齐全弹性,很容易实现存储和计算拆散架构;共享:能够被多个客户端同时读写;文件锁:反对 BSD 锁(flock)及 POSIX 锁(fcntl);数据压缩:默认应用 LZ4 压缩数据,节俭存储空间。我的项目架构JuiceFS 应用 Redis 来存储文件系统的元数据。Redis 是一个开源的内存数据库,能够保障元数据的高性能拜访。所有文件的数据会通过客户端存储到对象存储中,以下是它的架构图: JuiceFS 中的文件格式,如下图所示。一个文件首先被拆分成固定大小的 "Chunk",默认 64 MiB。每个 Chunk 能够由一个或者多个 "Slice" 组成,它们是变长的。对于每一个 Slice,又会被拆分成固定大小的 "Block",默认为 4 MiB(格式化后就不能够批改)。最初,这些 Block 会被压缩和加密保留到对象存储中。压缩和加密都是可选的。 性能测试程序读写性能 应用 fio 测试了 JuiceFS、EFS 和 S3FS 的程序读写性能,后果如下: 上图显示 JuiceFS 能够比其余两者提供 10 倍以上的吞吐。 元数据性能 应用 mdtest 测试了 JuiceFS、EFS 和 S3FS 的元数据性能,后果如下: 上图显示 JuiceFS 的元数据性能显著优于其余两个。 开发者说JuiceFS 的翻新架构更合乎云原生的发展趋势,咱们一开始就以 SaaS 的模式将它提供给私有云的客户,让客户分钟级就能够取得 PB 级企业文件存储服务。同时,咱们也和行业当先的对象存储厂商一起服务公有云客户。 ...

January 18, 2021 · 1 min · jiezi

关于redis:惊喜来袭253页全彩免费电子书Python-编程参考正式上线发布

这是一本写给开发者的⼯作必备根底书籍,凋谢在线浏览和 PDF 原稿下载,全书共 253 页/黑白 。 大家好,我是韦世东,一名由经营转行的 Python/Golang/Rust 开发者。 我本人的学习之旅走过许多弯路,也失去很多群友(这里特地点名我的 Python 指路人大鱼唐轶飞)的帮忙。因而在通过一段时间的积淀后决定把本人所把握的一些技术相干常识演绎整顿,冀望可能帮忙到和我一样酷爱学习的敌人。多年以前初入技术江湖,崔庆才跟我说“心愿当前你也可能帮忙那些有须要的人”,我铭刻于心,付诸实践。 残缺目录、下载地址、读者群在文末。 编程参考写了什么这本书的格调跟以往不同,这次主打实际落地为王。书的内容涵盖技术指南、代码的具体实现、事项具体落地执行,不再是浮于下层的思维领导,只有你照着书上的指引做,就可能间接利用在工作当中,简略间接无效,没有花里胡哨。 编程参考书中内容涵盖编程标准、程序设计、绘图指南、Python 罕用算法、Python 应用代码、技术治理和基础知识等几个类别,看完本书后代码程度能够晋升几个等级,而且很多工作困扰也能迎刃而解。内容粗疏且配图精美,上面请各位赏析。 PDF 下载地址这本收费的电子书官网惟一下载渠道为微信公众号 Python 编程参考,关注公众号并回复编程参考四个字即可获取下载地址,线上浏览地址为作者的技术专栏 https://www.weishidong.com。 凋谢状况如下 2021-01-17 17:00:00 微信公众号渠道放开; 2021-01-23 22:00:00 线上浏览渠道放开; 官网读者交换群作者会继续保护读者群,群内不容许呈现广告、闲聊和无意义内容,如果你对 Python、Golang、技术治理、经营、技术架构感兴趣,欢送增加作者微信 vansenb 并申请(增加时备注编程参考读者,如果你曾经有作者微信,间接发送编程参考读者即可)进入读者交换群。 残缺目录书籍以后版本为 V1.0,以季度为单位更新内容。提供线上地址收集勘误信息和内容征集,具体地址请翻阅《Python 编程参考》的前言局部。书籍残缺目录如下:

January 18, 2021 · 1 min · jiezi

关于redis:redis哨兵机制主库挂了如何不间断服务

以下均在单机环境下测试:实例A(主 127.0.0.1:16379 master)实例B(主 127.0.0.1:16380 slave1)实例C(主 127.0.0.1:16381 slave2) 失常主从redis服务图: master异样图: 由图可知,当master异样时,客户端不能写数据,从库不能从主库同步数据,这时候,咱们就须要运行一个新的主库,这里就波及到三个问题。 主库是否真的挂了?主库挂了的话,选哪个从库来充当主库?如何把新主库通知从库和客户端?哨兵机制,帮你解决所有问题。 哨兵机制次要性能:监控,选举,告诉 监控:判断主库是否挂了,判断分为两种:主观下线,主观下线。 主观下线:每个sentinel节点(哨兵节点)对redis节点的偏见 主观下线:所有sentinel节点(哨兵节点)对redis节点达成统选举:选出新的主库告诉:告诉客户端和其余从库 监控:哨兵ping从库,咦,ping超时了,间接标记为主观下线(此实例就不可用于服务)。哨兵ping主库,咦,也是ping不通,然而不能间接标记为主观下线,因为可能存在误判,误判会导致主从切换,带来不必要的切换开销,如从新选举,通信开销。 误判:主库没下线,哨兵认为主库下线了,可能呈现起因:集群网络压力较大、网络拥塞,或者是主库自身压力较大。那怎么缩小监控时的误判呢?采纳哨兵集群判断,由多个哨兵判断主库主观下线了,主库才会标记为主观下线。判断后果为下线: 判断后果为上线: 主观下线的规范就是,当有 N 个哨兵实例时,最好要有 N/2 + 1 个实例判断主库为“主观下线”,能力最终断定主库为“主观下线” 如何选举新主库?筛选 + 打分 咱们选新主库,必定是要新主库稳固,防止切换后再次发生主从切换。 先对新主库进行筛选:次要是判断新从库在线状态和网络连接状况。网络连接判断:能够判断sentinel配置down-after-milliseconds * 10,超过最大连贯超时工夫10 次,则从库网络不稳固,不适合做新主库。 打分:分为三轮规定。从库优先级、从库复制进度以及从库 ID号 从库优先级:如果从库的机器实例B(在此为16380端口)绝对比拟高配,能够通过redis.conf设置分高一点,比方设置为100分。实例C(在此为16381端口)绝对比拟低配,能够设置为70分。 此时master宕机,选举就会产生了,在此,咱们先来试验一下。启动哨兵,哨兵1为例子:port 23680 此时,让master(实例A,16379)下线。 察看哨兵反馈。再次查看主从状态再次启动实例A(16379),发现实例A变成了从库,成为实例B的主库。 如果从库优先级优先级统一,则旧主库同步水平最靠近的从库得分高,该从库成为新主库(起码缩小数据失落) 如果从库的slave_repl_offset都统一,则须要进行第三次打分。每个实例都会有一个 ID,这个 ID 就相似于这里的从库的编号。目前,Redis 在选主库时,有一个默认的规定:在优先级和复制进度都雷同的状况下,**ID 号最小的从库得分最高,会被选为新主库** 到此,主库切换就实现了。 总结:哨兵会依照在线状态、网络状态,筛选过滤掉一部分不符合要求的从库,而后,顺次依照优先级、复制进度、ID 号大小再对残余的从库进行打分,只有有得分最高的从库呈现,就把它选为新主库。

January 18, 2021 · 1 min · jiezi

关于redis:redis复制流程

January 16, 2021 · 0 min · jiezi

关于redis:redis主从数据同步流程

咱们常常据说redis具备高可靠性,这里的高可靠性有什么含意呢?① 数据少失落② 服务少中断 ①通过AOF,RDB保障②通过多实例保留数据备份保障,即多个机器都保留一份数据,即便机器A宕机了,也有机器B,机器C来服务。 那么redis如何保障各个机器的数据一致性呢?先想像,如果客户端操作了一个key,然而每次都是操作不同机器,比方机器A: set aaa 111机器B: set aaa 222机器C: set aaa 333 此时,咱们拜访不同机器时,失去key aaa的值都会不同,会对业务造成影响。 redis采纳的是主从模式来保障各机器备份数据的一致性,比方设置机器A为master(主),机器B,C为slave(从)读操作:A,B,C机器写操作:先写A机器,而后同步给B,C机器 主从库如何进行第一次数据同步?因机器数量无限,就在同一机器启动三个实例A, B, C。实例A:16379 端口(master)实例B:16379 端口(slave)实例C:16379 端口(slave)实例B,C都成为实例A的从库:执行slaveof 127.0.0.1 16379,就成为了实例A的从库。 具体流程: ① 实例B执行 slaveof 127.0.0.1 16379 ② psync runID offset , 实例B通知实例A,我须要要同步你数据参数1 runID, 代表实例A的惟一标识(redis实例启动后主动生成的惟一ID)参数2 offset,复制进度,这里 - 1 复制代表全量复制 ③ 实例A收回相应命令 FULLRESYNC RunID offset(FULLRESYNC 主库ID 主库复制进度)。 ④实例B保留实例A响应的runID offset。 ⑤实例A执行bgsave命令,生成RDB(实例A的所有数据),发送给实例B ⑥实例B清空本人所有数据,加载RDB文件 ⑦replication buffer 是什么呢?构想一下,实例A在生成RDB时和向实例B传输RDB文件时,有新的写申请怎么办?实例A生成和传输RDB过程必定不能拒绝服务,所以会先把操作记录到复制缓冲区,即replication buffer,等RDB文件发送实现后,再发送缓冲区的写操作,这样master和slave能力数据统一~~~~⑧加载replication buffer。 主从库间网络断了,主从数据不统一怎么办?redis2.8前, 主库会和从库从新进行一次全量复制。redis2.8后, 采纳增量复制,这里波及到 repl_backlog_buffer(环形缓冲复制队列),当主从库断连后,主库会把断连期间收到的写操作命令,写入 replication buffer(复制缓冲区),同时也会把这些操作命令也写入 repl_backlog_buffer(环形缓冲复制队列)。repl_backlog_buffer 是一个环形缓冲区,主库会记录本人写到的地位,从库则会记录本人曾经读到的地位。 主从网络中断复原连贯时,从库会通过psync命令把offset发给主库,主库把master_repl_offset(3)和 repl_backlog_buffer(1)之间的数据复制给从库就能够,则图中2,3局部即可~~~~。 ...

January 16, 2021 · 1 min · jiezi

关于redis:Redis第四章节基础知识

基础知识5种根本数据类型String(字符串)String是redis最根本的数据类型,一个key对应一个value。String类型的值最大能存储512M。Hash(哈希)Hash相当于双重map。每个Hash能够存储40多亿键值对。List(列表)redis列表是简略的字符串列表。每个列表能够存储40多亿元素。Set(无序汇合)每个汇合能够存储40多亿元素。zSet(有序汇合)服务器操作命令形容bgrewriteaof异步执行一个AOF文件重写操作bgsave在后盾异步保留以后数据库的数据到磁盘client kill [ip port] [ID client-id]敞开客户端连贯client list获取连贯到服务器的客户端列表client getname获取连贯的名称client pause timeout在指定工夫内终止运行来自客户端的命令client setname connection-name设置以后连贯的名称cluster slots获取集群节点的映射数组dbsize返回以后数据库key的数量flushall删除所有数据库的所有的keyflushdb删除以后数据库的所有的keylastsave返回最近一次redis胜利将数据保留到磁盘上的工夫save同步保留数据到硬盘select [numer]抉择指定的数据库

January 16, 2021 · 1 min · jiezi

关于redis:Redis第三章节安装和配置

官网地址 https://redis.io/下载 wget https://download.redis.io/releases/redis-6.0.10.tar.gz 装置 cd redis-6.0.10 make cd src make install PREFIX=/usr/local/redis留神: make 编译失败,可能因为没有 gcc 服务 查看 gcc 是否装置 rep -qa|grep gcc 装置 gcc yum -y install gcc yum -y install gcc-c++ 将配置文件挪动到装置目录 mv redis.conf /usr/local/redis/etc 启动服务 /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf默认状况下,redis 不是后盾启动,设置后盾启动 vim redis.conf 将daemonize的值改为yesredis 开机自启 vim /etc/rc.local 退出 /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis-conf设置权限登录 1、正文掉redis装置目录下的redis.conf文件中的如下数据:bind 127.0.0.1,正文#bind 127.0.0.1 或者批改bind 0.0.0.0。 2、批改保护模式为非:默认为protected-mode yes ,批改后为protected-mode no。 3、设置redis连贯明码:找到 requirepass foobared,在上面增加 requirepass 123456。带明码的命令行登录 带明码的启动形式 ./redis-cli -h 127.0.0.1 -p 6379 -a 123456 -h 是主机IP地址 -p 是端口号 -a 是明码

January 16, 2021 · 1 min · jiezi

关于redis:Redis-60-集群搭建实践

本文是Redis集群学习的实际总结(基于Redis 6.0+),具体介绍逐渐搭建Redis集群环境的过程,并实现集群伸缩的实际。 Redis集群简介Redis集群(Redis Cluster) 是Redis提供的分布式数据库计划,通过 分片(sharding) 来进行数据共享,并提供复制和故障转移性能。相比于主从复制、哨兵模式,Redis集群实现了较为欠缺的高可用计划,解决了存储能力受到单机限度,写操作无奈负载平衡的问题。 本文是Redis集群学习的实际总结,具体介绍逐渐搭建Redis集群环境的过程,并实现集群伸缩的实际。 Redis集群环境搭建不便起见,这里集群环境的所有节点全副位于同一个服务器上,共6个节点以端口号辨别,3个主节点+3个从节点。集群的简略架构如图:本文基于最新的Redis 6.0+,间接从github下载最新的源码编译取得常用工具 redis-server ,  redis-cli 。值得注意的是,从Redis 5.0当前的版本,集群管理软件 redis-trib.rb 被集成到 redis-cli 客户端工具中(具体可参考cluster-tutorial)。 本节介绍集群环境搭建时,并未借助 redis-trib.rb 疾速治理,而是依照规范步骤一步步搭建,这也是为了相熟集群治理的根本步骤。在集群伸缩实际一节将借助 redis-trib.rb 实现集群从新分片工作。 集群的搭建能够分为四步: 启动节点:将节点以集群形式启动,此时节点是独立的。节点握手:将独立的节点连成网络。槽指派:将16384个槽位调配给主节点,以达到分片保留数据库键值对的成果。主从复制:为从节点指定主节点。启动节点 每个节点初始状态仍为 Master服务器,惟一不同的是:应用 Cluster 模式启动。须要对配置文件进行批改,以端口号为6379的节点为例,次要批改如下几项: # redis_6379_cluster.confport 6379cluster-enabled yescluster-config-file "node-6379.conf"logfile "redis-server-6379.log"dbfilename "dump-6379.rdb"daemonize yes其中 cluster-config-file 参数指定了集群配置文件的地位,每个节点在运行过程中,会保护一份集群配置文件;每当集群信息发生变化时(如增减节点),集群内所有节点会将最新信息更新到该配置文件;当节点重启后,会从新读取该配置文件,获取集群信息,能够不便的重新加入到集群中。也就是说,当Redis节点以集群模式启动时,会首先寻找是否有集群配置文件,如果有则应用文件中的配置启动,如果没有,则初始化配置并将配置保留到文件中。集群配置文件由Redis节点保护,不须要人工批改。 为6个节点批改好相应的配置文件后,即可利用 redis-server redis_xxxx_cluster.conf 工具启动6个服务器(xxxx示意端口号,对应相应的配置文件)。利用ps命令查看过程: $ ps -aux | grep redis... 800  0.1  0.0  49584  2444 ?        Ssl  20:42   0:00 redis-server 127.0.0.1:6379 [cluster]... 805  0.1  0.0  49584  2440 ?        Ssl  20:42   0:00 redis-server 127.0.0.1:6380 [cluster]... 812  0.3  0.0  49584  2436 ?        Ssl  20:42   0:00 redis-server 127.0.0.1:6381 [cluster]... 817  0.1  0.0  49584  2432 ?        Ssl  20:43   0:00 redis-server 127.0.0.1:6479 [cluster]... 822  0.0  0.0  49584  2380 ?        Ssl  20:43   0:00 redis-server 127.0.0.1:6480 [cluster]... 827  0.5  0.0  49584  2380 ?        Ssl  20:43   0:00 redis-server 127.0.0.1:6481 [cluster]节点握手 将下面的每个节点启动后,节点间是互相独立的,他们都处于一个只蕴含本人的集群当中,以端口号6379的服务器为例,利用 CLUSTER NODES 查看以后集群蕴含的节点。 127.0.0.1:6379> CLUSTER NODES37784b3605ad216fa93e976979c43def42bf763d :6379@16379 myself,master - 0 0 0 connected 449 4576 5798 7568 8455 12706咱们须要将各个独立的节点连接起来,形成一个蕴含多个节点的集群,应用 CLUSTER MEET 命令。 $ redis-cli -p 6379 -c          # -c 选项指定以Cluster模式运行redis-cli 127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6380 OK 127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6381 OK 127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6480 OK 127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6381 OK 127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6382 OK再次查看此时集群中蕴含的节点状况: 127.0.0.1:6379> CLUSTER NODESc47598b25205cc88abe2e5094d5bfd9ea202335f 127.0.0.1:6380@16380 master - 0 1603632309283 4 connected87b7dfacde34b3cf57d5f46ab44fd6fffb2e4f52 127.0.0.1:6379@16379 myself,master - 0 1603632308000 1 connected51081a64ddb3ccf5432c435a8cf20d45ab795dd8 127.0.0.1:6381@16381 master - 0 1603632310292 2 connected9d587b75bdaed26ca582036ed706df8b2282b0aa 127.0.0.1:6481@16481 master - 0 1603632309000 5 connected4c23b25bd4bcef7f4b77d8287e330ae72e738883 127.0.0.1:6479@16479 master - 0 1603632308000 3 connected32ed645a9c9d13ca68dba5a147937fb1d05922ee 127.0.0.1:6480@16480 master - 0 1603632311302 0 connected能够发现此时6个节点均作为主节点退出到集群中, CLUSTER NODES 返回的后果各项含意如下: <id> <ip:port@cport> <flags> <master> <ping-sent> <pong-recv> <config-epoch> <link-state> <slot> <slot> ... <slot>节点id: 由40个16进制字符串组成,节点id只在集群初始化时创立一次,而后保留到集群配置文件(即前文提到的cluster-config-file)中,当前节点重新启动时会间接在集群配置文件中读取。port@cport: 前者为一般端口,用于为客户端提供服务;后者为集群端口,调配办法为:一般端口+10000,只用于节点间的通信。其余各项的具体解释能够参考官网文档cluster nodes。 槽指派 Redis集群通过分片(sharding)的形式保留数据库的键值对,整个数据库被分为16384个槽(slot),数据库每个键都属于这16384个槽的一个,集群中的每个节点都能够解决0个或者最多16384个slot。 槽是数据管理和迁徙的根本单位。当数据库中的16384个槽都调配了节点时,集群处于上线状态(ok);如果有任意一个槽没有调配节点,则集群处于下线状态(fail)。 留神,只有主节点有解决槽的能力,如果将槽指派步骤放在主从复制之后,并且将槽位调配给从节点,那么集群将无奈失常工作(处于下线状态)。 利用 CLUSTER ADDSLOTS redis-cli  -p 6379 cluster addslots {0..5000}redis-cli  -p 6380 cluster addslots {5001..10000}redis-cli  -p 6381 cluster addslots {10001..16383}槽指派后集群中节点状况如下: 127.0.0.1:6379> CLUSTER NODESc47598b25205cc88abe2e5094d5bfd9ea202335f 127.0.0.1:6380@16380 master - 0 1603632880310 4 connected 5001-10000 87b7dfacde34b3cf57d5f46ab44fd6fffb2e4f52 127.0.0.1:6379@16379 myself,master - 0 1603632879000 1 connected 0-5000 51081a64ddb3ccf5432c435a8cf20d45ab795dd8 127.0.0.1:6381@16381 master - 0 1603632879000 2 connected 10001-16383 9d587b75bdaed26ca582036ed706df8b2282b0aa 127.0.0.1:6481@16481 master - 0 1603632878000 5 connected4c23b25bd4bcef7f4b77d8287e330ae72e738883 127.0.0.1:6479@16479 master - 0 1603632880000 3 connected32ed645a9c9d13ca68dba5a147937fb1d05922ee 127.0.0.1:6480@16480 master - 0 1603632881317 0 connected127.0.0.1:6379> CLUSTER INFOcluster_state:ok                        # 集群处于上线状态cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:5 cluster_my_epoch:1 cluster_stats_messages_ping_sent:4763 cluster_stats_messages_pong_sent:4939 cluster_stats_messages_meet_sent:5 cluster_stats_messages_sent:9707 cluster_stats_messages_ping_received:4939 cluster_stats_messages_pong_received:4768 cluster_stats_messages_received:9707主从复制上述步骤后,集群节点均作为主节点存在,仍不能实现Redis的高可用,配置主从复制之后,才算真正实现了集群的高可用性能。 CLUSTER REPLICATE <node_id> 用来让集群中接管命令的节点成为 node_id 所指定节点的从节点,并开始对主节点进行复制。 ...

January 15, 2021 · 1 min · jiezi

关于redis:一文带你探究Sentinel的独特初始化

摘要:本系列通过作者对Redis Sentinel源码的了解,具体阐明Sentinel的代码实现形式。Redis Sentinel 是Redis提供的高可用模型解决方案。Sentinel能够主动监测一个或多个Redis主备实例,并在主实例宕机的状况下主动履行主备倒换。本系列通过作者对Redis Sentinel源码的了解,具体阐明Sentinel的代码实现形式。 Sentinel应用Redis内核雷同的事件驱动代码框架, 但Sentinel有本人独特的初始化步骤。在这篇文章里,作者会介绍Sentinel与Redis服务器不同的初始化局部。 咱们能够通过redis-sentinel <path-to-configfile> 或者 redis-server <path-to-configfile> --sentinel 这两种形式启动并运行Sentinel实例,这两种形式是等价的。在Redis server.c 的main函数中,咱们会看到Redis如何判断用户指定以Sentinel形式运行的逻辑: int main(int argc, char **argv) { .......... server.sentinel_mode = checkForSentinelMode(argc,argv); .......... } 其中checkForSentinelMode函数会监测以下两种条件: 程序应用redis-sentinel可执行文件执行。程序参数列表中有--sentinel 标记。以上任何一种条件成立则Redis会应用Sentinel的形式运行。 /* Returns 1 if there is --sentinel among the arguments or if * argv[0] contains "redis-sentinel". */ int checkForSentinelMode(int argc, char **argv) { int j; if (strstr(argv[0],"redis-sentinel") != NULL) return 1; for (j = 1; j < argc; j++) if (!strcmp(argv[j],"--sentinel")) return 1; return 0; }在Redis 判断是否以Sentinel的形式运行当前,咱们会看到如下代码段: ...

January 15, 2021 · 3 min · jiezi

关于redis:面试官你真的了解Redis分布式锁吗

什么是分布式锁说到Redis,咱们第一想到的性能就是能够缓存数据,除此之外,Redis因为单过程、性能高的特点,它还常常被用于做分布式锁。 锁咱们都晓得,在程序中的作用就是同步工具,保障共享资源在同一时刻只能被一个线程拜访,Java中的锁咱们都很相熟了,像synchronized 、Lock都是咱们常常应用的,然而Java的锁只能保障单机的时候无效,分布式集群环境就无能为力了,这个时候咱们就须要用到分布式锁。 分布式锁,顾名思义,就是分布式我的项目开发中用到的锁,能够用来管制分布式系统之间同步访问共享资源,一般来说,分布式锁须要满足的个性有这么几点: 1、互斥性:在任何时刻,对于同一条数据,只有一台利用能够获取到分布式锁; 2、高可用性:在分布式场景下,一小部分服务器宕机不影响失常应用,这种状况就须要将提供分布式锁的服务以集群的形式部署; 3、避免锁超时:如果客户端没有被动开释锁,服务器会在一段时间之后主动开释锁,避免客户端宕机或者网络不可达时产生死锁; 4、独占性:加锁解锁必须由同一台服务器进行,也就是锁的持有者才能够开释锁,不能呈现你加的锁,他人给你解锁了; 业界里能够实现分布式锁成果的工具很多,但操作无非这么几个:加锁、解锁、避免锁超时。 既然本文说的是Redis分布式锁,那咱们天经地义就以Redis的知识点来延长。 实现锁的命令先介绍下Redis的几个命令, 1、SETNX,用法是SETNX key value SETNX是『 SET if Not eXists』(如果不存在,则 SET)的简写,设置胜利就返回1,否则返回0。 setnx用法 能够看出,当把key为lock的值设置为"Java"后,再设置成别的值就会失败,看上去很简略,也如同独占了锁,但有个致命的问题,就是key没有过期工夫,这样一来,除非手动删除key或者获取锁后设置过期工夫,不然其余线程永远拿不到锁。 既然这样,咱们给key加个过期工夫总能够吧,间接让线程获取锁的时候执行两步操作: `SETNX Key 1``EXPIRE Key Seconds`这个计划也有问题,因为获取锁和设置过期工夫分成两步了,不是原子性操作,有可能获取锁胜利但设置工夫失败,那样不就白干了吗。 不过也不必急,这种事件Redis官网早为咱们思考到了,所以就引出了上面这个命令 2、SETEX,用法SETEX key seconds value 将值 value 关联到 key ,并将 key 的生存工夫设为 seconds (以秒为单位)。如果 key 曾经存在,SETEX 命令将覆写旧值。 这个命令相似于以下两个命令: `SET key value``EXPIRE key seconds  # 设置生存工夫`这两步动作是原子性的,会在同一时间实现。 setex用法 3、PSETEX ,用法PSETEX key milliseconds value 这个命令和SETEX命令类似,但它以毫秒为单位设置 key 的生存工夫,而不是像SETEX命令那样,以秒为单位。 不过,从Redis 2.6.12 版本开始,SET命令能够通过参数来实现和SETNX、SETEX、PSETEX 三个命令雷同的成果。 就比方这条命令 `SET key value NX EX seconds` 加上NX、EX参数后,成果就相当于SETEX,这也是Redis获取锁写法外面最常见的。 怎么开释锁开释锁的命令就简略了,间接删除key就行,但咱们后面说了,因为分布式锁必须由锁的持有者本人开释,所以咱们必须先确保以后开释锁的线程是持有者,没问题了再删除,这样一来,就变成两个步骤了,仿佛又违反了原子性了,怎么办呢? 不慌,咱们能够用lua脚本把两步操作做拼装,就如同这样: `if redis.call("get",KEYS[1]) == ARGV[1]``then` `return redis.call("del",KEYS[1])``else` `return 0``end`KEYS[1]是以后key的名称,ARGV[1]能够是以后线程的ID(或者其余不固定的值,能辨认所属线程即可),这样就能够避免持有过期锁的线程,或者其余线程误删现有锁的状况呈现。 代码实现晓得了原理后,咱们就能够手写代码来实现Redis分布式锁的性能了,因为本文的目标次要是为了解说原理,不是为了教大家怎么写分布式锁,所以我就用伪代码实现了。 首先是redis锁的工具类,蕴含了加锁和解锁的根底办法: `public class RedisLockUtil {` `private String LOCK_KEY = "redis_lock";` `// key的持有工夫,5ms` `private long EXPIRE_TIME = 5;` `// 期待超时工夫,1s` `private long TIME_OUT = 1000;` `// redis命令参数,相当于nx和px的命令合集` `private SetParams params = SetParams.setParams().nx().px(EXPIRE_TIME);` `// redis连接池,连的是本地的redis客户端` `JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);` `/**` `* 加锁` `*` `* @param id` `*            线程的id,或者其余可辨认以后线程且不反复的字段` `* @return` `*/` `public boolean lock(String id) {` `Long start = System.currentTimeMillis();` `Jedis jedis = jedisPool.getResource();` `try {` `for (;;) {` `// SET命令返回OK ,则证实获取锁胜利` `String lock = jedis.set(LOCK_KEY, id, params);` `if ("OK".equals(lock)) {` `return true;` `}` `// 否则循环期待,在TIME_OUT工夫内仍未获取到锁,则获取失败` `long l = System.currentTimeMillis() - start;` `if (l >= TIME_OUT) {` `return false;` `}` `try {` `// 休眠一会,不然重复执行循环会始终失败` `Thread.sleep(100);` `} catch (InterruptedException e) {` `e.printStackTrace();` `}` `}` `} finally {` `jedis.close();` `}` `}` `/**` `* 解锁` `*` `* @param id` `*            线程的id,或者其余可辨认以后线程且不反复的字段` `* @return` `*/` `public boolean unlock(String id) {` `Jedis jedis = jedisPool.getResource();` `// 删除key的lua脚本` `String script = "if redis.call('get',KEYS[1]) == ARGV[1] then" + "   return redis.call('del',KEYS[1]) " + "else"` `+ "   return 0 " + "end";` `try {` `String result =` `jedis.eval(script, Collections.singletonList(LOCK_KEY), Collections.singletonList(id)).toString();` `return "1".equals(result);` `} finally {` `jedis.close();` `}` `}``}`具体的代码作用正文曾经写得很分明了,而后咱们就能够写一个demo类来测试一下成果: ...

January 15, 2021 · 1 min · jiezi

关于redis:redis-fork-copy-on-write

forkfork创立一个子过程,原来过程叫父过程fork()调用的一个微妙之处就是它仅仅被调用一次,却可能返回两次,它可能有三种不同的返回值: 该过程为父过程时,返回子过程的pid该过程为子过程时,返回0fork执行失败,返回-1常见模式: fork出错可能有2种起因: 以后的过程数曾经达到了零碎规定的下限零碎内存不足写时复制在fork之后两个过程 用的是雷同的物理空间(内存区),子过程的代码段、数据段、堆栈都是指向父过程的物理空间,也就是说,两者的虚拟空间不同,但其对应的 物理空间是同一个。 当父子过程中有更改相应段的行为产生时,再为子过程相应的段调配物理空间。 实现原理:fork()之后,kernel把父过程中所有的内存页的权限都设为read-only,而后子过程的地址空间指向父过程。当父子过程都只读内存时,相安无事。当其中某个过程写内存时,CPU硬件检测到内存页是read-only的,于是触发页异常中断(page-fault),陷入kernel的一个中断例程。中断例程中,kernel就会 把触发的异样的页复制一份,于是父子过程各自持有独立的一份。 参考https://blog.csdn.net/qq_3455...https://zhuanlan.zhihu.com/p/...

January 13, 2021 · 1 min · jiezi

关于redis:redis持久化

January 13, 2021 · 0 min · jiezi

关于redis:redis6安装报错You-need-tcl-85-or-newer-in-order

问题linux装置redis6.x时候,make test后有谬误如下 You need tcl 8.5 or newer in order to run the Redis test解决办法1.间接装置新的tcl,命令如下: yum install -y tcl-devel2.清空之前的make的缓存命令: make distclean3.从新make编译命令: make4.完结后从新测试命令: make test完结具体其余装置命令 能够查看 redis解压后的目录下 README.MD

January 13, 2021 · 1 min · jiezi

关于redis:Redis第二章节简介

简介概要: 起源: 2008年,意大利一家守业公司Merzia推出了一款基于mysql的网站统计零碎LLOOGG,然而没过多久公司的创世人对mysql的性能感到悲观,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年实现。始终继续更新到当初的6.0.9版本。NoSQL: 定义: 泛指非关系性数据库的。特点: 不便扩大,数据之间没有关系。大数据量高性能。数据类型多样性。能够再和传统RDBMS和NoSQL比照一下。NoSQL四大分类: kv键值对: 新浪:Redis。美团:Redis + Tair。阿里、百度:Redis + memercache。文档型数据库: MongoDB: MongDB是一个基于分布式文件存储的数据库,由 c++ 编写,次要用来解决大量的文档!MongDB是一个介于关系型数据库和非关系型数据库两头的产品,MongDB是非关系型数据库中性能最丰盛,最像关系型数据库的。CouchDB:列存储数据库: HBase。分布式文件系统。图关系数据库: Neo4j、InfoGrid。Redis入门: 概要: redis是什么: Redis是一个开源的ANSIc语言编写、反对网络、可基于内存亦可长久化的日志型、key-value数据库,并提供多种语言的API。作用: 内存存储、长久化(内存是断电就会失落的、所有长久化很重要(RDB、AOF))。效率高,能够高速缓存。公布订阅零碎。地图信息剖析。计数器、计数器。个性: 多样的数据类型长久化集群事务。。。

January 13, 2021 · 1 min · jiezi

关于redis:Redis第一章节引导

Redis专题目录根底 简介装置和配置基础知识数据类型事物长久化公布订阅利用场景进阶 动静字符串-string链表和节点-list字典-hashintset和hashtable-setskiplist-zSet

January 13, 2021 · 1 min · jiezi

关于redis:Redis常见问题

Redis有哪些利用场景?1) 缓存2) 排行榜零碎(有序汇合zset)3) 计数器利用4) 社交网络5) 音讯队列6) 限速,例如一分钟不能超过5次7) 标签(汇合) Redis的线程模型Redis为什么快?纯内存拜访非阻塞IO,应用epoll作为IO多路复用技术的实现单线程防止了线程切换合竞争产生的耗费数据迁徙Redis数据淘汰策略

January 11, 2021 · 1 min · jiezi

关于redis:Redis-单机哨兵集群搭建

1. Redis 单机搭建(以 6.0.6 版本为例)装置 gcc 套装。 yum install cppyum install binutilsyum install glibcyum install glibc-kernheadersyum install glibc-commonyum install glibc-develyum install gccyum install make降级 gcc。 yum -y install centos-release-sclyum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutilsscl enable devtoolset-9 bash使 scl 长期有效。 echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile下载 redis 。 wget http://download.redis.io/releases/redis-6.0.6.tar.gz解压。 tar vxf redis-6.0.6.tar.gz编译,装置。 cd redis-6.0.6/makemake PREFIX=/usr/local/redis install创立配置文件、数据目录,并且将配置文件复制到目录中。 mkdir /usr/local/redis/confmkdir /usr/local/redis/datacp ${REDIS_SRC_HOME}/redis.conf /usr/local/redis/conf/批改配置文件 conf/redis.conf。 批改其中对应的内容。# 后盾启动的意思daemonize yes # IP绑定,redis不倡议对公网凋谢,间接绑定 0.0.0.0 没故障bind 0.0.0.0# redis数据文件寄存的目录dir /usr/local/redis/data# 开启AOFappendonly yes启动 redis。 ...

January 7, 2021 · 3 min · jiezi

关于redis:Redis基本操作

title: Redis基本操作categories: [Redis]tags: [数据库]date: 2021/01/06 作者:hackett 微信公众号:加班猿 一、redis根本数据类型redis保留的数据都是依照键值对来保留键(key)值(value)键的数据类型都是字符串值的类型有以下五种: 字符串(string)哈希(hash)列表(list)无序汇合(set)有序汇合(zset)二、字符串(string)增加批改字符串set 键 值 如果键不存在,就是增加如果键存在,就是批改 set user tom # 增加一个键user值为tom set user hackett # 把user的值改为hackettsetex 键 过期工夫 值 过期工夫单位为秒 setex user 5 jerry # 增加一个键user值为jerry,过期工夫为5秒增加多个键值对 -- mset 键1 值1 键2 值2 键3 值3 ...... mset user1 tom user2 hackett user3 jerry # 同时增加3个键值对已有值前面追加 -- append 键 值 append user1 haha # 向user1中追加值 haha获取值get 键 get user # 获取user的值mget 键1 键2 键3 ...... mget user1 user2 user3 # 获取3个键的值删除键del 键1 键2 键3 del user1 user2 user3 # 删除3个键三、键命令查找键keys 键名能够反对 * keys user1 # 查看键user1是否存在 keys * # 查看所有键判断键是否存在exists 键如果存在,返回1如果不存在,返回0exists user1# 判断user1是否存在查看对应键的value类型type 键type user1# 查看user1对应的值的类型设置已有键的过期工夫expire 键 秒数expire user1 5# 设置user1的过期工夫为5s查看键过期工夫ttl 键返回0,代表无效工夫,单位:秒返回-1,代表永远无效返回-2,代表键不存在ttl key# 查看key的无效工夫四、哈希hash增加值hset 键 字段 值hset user1 name tom# 减少一个hash类型的键值对,字段为name,值为tom增加多个值hmset 键 字段1 值1 字段2 值2 ......hmset user2 name jerry sex female# 增加user2的键,字段有两个获取字段hkeys 键获取制订键的所有字段名hkeys user2# 获取键user2的所有字段获取字段对应的值hget 键 字段hget user2 sex# 获取user2键字段sex的值获取多个字段的值hmget 键 字段1 字段2hmget user2 name sex# 获取user2键字段name,sex的值获取键所有字段的值hvals 键hvals user2# 获取user2所有字段的值获取键所有字段和值hgetall 键hgetall user2# 获取user2的字段和值删除字段hdel 键 字段hdel user2 sex# 删除user2的sex字段删除键hdel 键hdel user2# 删除user2的键五、列表list增加值lpush 键 值1 值2 ......从列表左侧增加值lpush luser1 tom# 新建一个luser1的键,在左侧增加tom的值 值:tomrpush 键 值1 值2 ......从列表右侧增加值rpush luser1 jerry# 新建一个luser1的键,在右侧增加tom的值 值:tomjerry插入值linsert 键 before 或者 after 值 新值在制订的值后面或者前面插入新值linsert luser1 before jerry 11# 在jerry后面插入新值11 值:tom11jerrylinsert luser1 after jerry 22# 在jerry前面插入新值22 值:tom11jerry22获取lrange 键 start stop (返回列表里指定范畴的值)索引从左侧开始,第一个值的索引为0索引能够是正数,示意从尾部开始计数,如:-1代表最初一个值,-2代表倒数第二个值start,stop为要获取值的索引lrange luser1 0 -1# 获取开始到结尾的值lrange luser1 2 -1# 获取从第三个到最初的值批改lset 键 索引 值改指定索引的值lset luser1 1 haha# 把第二个元素的值改为haha删除值lrem 键 count 值count = 0 删除指定的所有值count < 0 删除从右往左指定数量的值count > 0 删除从左往右指定数量的值lrem luser2 -1 h0# 从后往前/从右往左,删除第一个h0lrem luser2 0 h0# 删除所有的h0六、无序汇合set增加值sadd 键 值1 值2 值3 ......sadd suser aa bb cc# 给键suser增加三个值获取值smembers 键获取汇合的值smembers suser# 获取键suser所有的值删除值srem 键 值删除指定的值srem suser aa# 删除键suser的值aa七、有序汇合zset增加值zadd 键 score1 值1 score2 值2增加值zadd zuser 1 aa 3 bb 2 cc 5 dd# 给键zuser增加4个值,并依照score从小到大主动排序 值:aaccbbdd获取值zrange 键 start stop [withscores]start 从 0开始最初一个索引为-1withscores代表同时获取scorezrange zuser 0 -1 withscores# 获取键zuser的所有值通过score获取值zrangebyscore 键 min maxmin代表score起始值max代表score完结值zrangebyscore zuser 2 6# 获取score从2到6的值通过值获取scorezscore 键 值失去指定值的scorezscore zuser dd# 失去值dd的score删除zrem 键 值删除指定的值zrem zuser dd# 删除值dd通过score删除值zremrangebyscore 键 min maxmin是要删除score的最小值max是要删除score的最大值zremrangebyscore zuser 0 10# 删除score从0到10到值如果你感觉文章还不错,记得"点赞关注" ...

January 6, 2021 · 2 min · jiezi

关于redis:Redis的安装

title: Redis装置categories: [Redis]tags: [数据库]date: 2020/01/04 作者:hackett 微信公众号:加班猿 一、Linux源码装置去官网下载最新的版本6.0.9,下载地址:https://redis.io/download Download, extract and compile Redis with:  wget https://download.redis.io/releases/redis-6.0.9.tar.gz  tar xzf redis-6.0.9.tar.gz //解压 cd redis-6.0.9 //进入源码目录 make //间接make装置在make过程中可能存在以下报错的状况  make: *** [server.o] Error 1 //make装置报错起因是: gcc版本过低,centos yum装置的gcc是4.8.5的。因而须要降级gcc,降级过程如下:  yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile gcc -v二、Ubuntu apt命令装置应用apt命令装置  sudo apt-get update sudo apt-get install redis-server三、启动服务并测试进入src目录并后盾启动redis服务  cd src ./redis-server & //后盾运行应用客户端程序redis-cli和redis服务交互  ./redis-cli //启动redis客户端上面咱们来测试一下(127.0.0.1是本机IP,6397是redis的服务端口号)  [root@VM-0-11-centos src]# ./redis-cli 127.0.0.1:6379> 127.0.0.1:6379> set foo bar OK 127.0.0.1:6379> get foo "bar" 127.0.0.1:6379>redis的配置(通过批改 redis.conf 文件或应用 CONFIG set 命令来批改配置,CONFIG get 命令查看设置配置项) ...

January 6, 2021 · 1 min · jiezi

关于redis:不要老盯着redis分布式锁这绝对不是一个简单的方案

分布式锁相比拟多线程锁,更加高级一些。它的作用范畴,也由单机转换为分布式,是罕用的资源协调伎俩。罕用的有redis分布式做和zk分布式锁。但它们有什么区别呢?咱们在平时应用中,又该如何抉择。 解析这个问题对要求较高,它不仅要理解实现办法,还要对原理有所把握。所以问题答复起来,分为很多档次。 家喻户晓,Redis标榜的是轻量级,直观上分布式锁是比拟好实现的,比方应用setnx,但一旦退出高可用这个属性,Redis锁的实现难度就会爆炸式回升。 再加上锁的其余几个属性:乐观乐观、读写锁等,事件会更加的简单。 如果你全都通晓,聊一天都聊不完。 尝试剖析以下先来一个,比拟通俗、入门的剖析: redis的分布式锁,能够基于setnx指令实现(但其实更倡议应用带nx参数的set指令)zk的分布式锁,是基于长期节点的有序性和节点的监听机制实现的 这种答复形式,间接把本人给绕进去了,因为这波及到十分多的细节。他人只是问区别,为什么把本人往源码级别绕呢? 倡议这样剖析: Redis,应用redisson封装的RedLockZk,应用curator封装的InterProcessMutex 比照: 实现难度上:Zookeeper >= redis服务端性能:redis > Zookeeper客户端性能:Zookeeper > redis可靠性:Zookeeper > redis 细聊: 2.1 实现难度 对于间接操纵底层API来说,实现难度都是差不多的,都须要思考很多边界场景。但因为Zk的ZNode人造具备锁的属性,所以间接上手撸的话,很简略。 Redis须要思考太多异样场景,比方锁超时、锁的高可用等,实现难度较大。 2.2 服务端性能 Zk基于Zab协定,须要一半的节点ACK,才算写入胜利,吞吐量较低。如果频繁加锁、开释锁,服务端集群压力会很大。 Redis基于内存,只写Master就算胜利,吞吐量高,Redis服务器压力小。 2.3 客户端性能 Zk因为有告诉机制,获取锁的过程,增加一个监听器就能够了。防止了轮询,性能耗费较小。 Redis并没有告诉机制,它只能应用相似CAS的轮询形式去争抢锁,较多空转,会对客户端造成压力。 2.4 可靠性 这个就很显著了。Zookeeper就是为协调而生的,有严格的Zab协定控制数据的一致性,锁模型强壮。 Redis谋求吞吐,可靠性上稍逊一筹。即便应用了Redlock,也无奈保障100%的健壮性,但个别的利用不会遇到极其场景,所以也被罕用。 扩大Zk的分布式锁样代码样例: import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.recipes.locks.InterProcessMutex;import java.util.concurrent.TimeUnit;public class ExampleClientThatLocks{ private final InterProcessMutex lock; private final FakeLimitedResource resource; private final String clientName; public ExampleClientThatLocks(CuratorFramework client, String lockPath, FakeLimitedResource resource, String clientName) { this.resource = resource; this.clientName = clientName; lock = new InterProcessMutex(client, lockPath); } public void doWork(long time, TimeUnit unit) throws Exception { if ( !lock.acquire(time, unit) ) { throw new IllegalStateException(clientName + " could not acquire the lock"); } try { System.out.println(clientName + " has the lock"); resource.use(); } finally { System.out.println(clientName + " releasing the lock"); lock.release(); // always release the lock in a finally block } }}RedLock的分布式锁应用样例: ...

January 6, 2021 · 3 min · jiezi

关于redis:带你认识大数据从0到1搭建-Hadoop-集群

大数据简介,概念局部概念局部,倡议之前没有任何大数据相干常识的敌人浏览 大数据概论什么是大数据大数据(Big Data)是指无奈在肯定工夫范畴内用惯例软件工具进行捕获、治理和解决的数据汇合,是须要新解决模式能力具备更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产 粗略解读以下 惯例软件工具:例如 JavaEE、Mysql(500-1000w数据)即便构建 Mysql 集群,集群中节点的数量也不是有限减少的。海量、高增长率:数据自身基数大,每天新退出的数据也多多样化:除了文本数据外,还有图片、视频等数据次要解决海量数据的存储和海量数据的剖析计算问题 大数据的特点大量:依据 IDC “数字宇宙” 报告 预计到2020年,寰球数据使用量将达到35.2ZB高速:在海量的数据背后,解决数据的效率就是企业的生命多样 结构化数据:数据库、文本为主非结构化数据:网络日志、音频、视频、图片、地理位置信息低价值密度:价值密度的高下与数据总量的大小成反比,疾速对有价值数据“提纯”大数据利用场景物流仓储:大数据分析系统助力商家精细化经营、晋升销量、节约老本批发:剖析用户生产习惯,为用户购买商品提供方便,从而晋升商品销量 国外案例:纸尿裤+啤酒,剖析过往的商超订单发现纸尿裤+啤酒同时呈现的概率很高,因而将这两样物品放在一起,刺激更多的人生产游览:深度联合大数据能力与游览行业需要,共建游览产业智慧治理、智慧服务和智慧营销的将来商品广告举荐:给用户举荐可能喜爱的商品(千人千面)保险、金融、房地产:数据挖掘、危险预测大数据发展前景十八大:施行国家大数据倒退策略 十九大:推动互联网、大数据、人工智能和实体经济深度交融 Hadoop简介Hadoop 是 Apache 基金会开发的分布式系统基础架构,次要解决海量数据的存储和剖析计算问题。与大数据所钻研的方向一样。狭义上来说,Hadoop通常指的是 Hadoop 的生态圈。我了解就和 Javaer 常说的 Spring Cloud 一样,并不特指一个技术,而是一些携手解决一个简单问题的汇合 创始人 Doug Cutting ,借鉴谷歌三篇论文 GFS ---> HDFS 解决了数据存储的问题 Map-Reduce ---> MR 解决了数据分析计算的问题 BigTable ---> HBase NoSQL数据库 三大发行版本Apache 最原始,最根底版本,适宜入门学习 Cloudera CDH版本、2008年成立,2009年Doug Cutting 加盟。 次要在大型互联网企业中应用,收费应用,付费保护 Hortonworks 2011年成立,文档较好,市场份额小 劣势高可靠性:底层保护多个数据正本(default 3)高扩展性:在集群间分配任务数据,可不便的扩大数以千计的节点高效性:在MapReduce的思维下,Hadoop是并行工作的高容错性:可能主动将失败的工作重新分配组成 2.x 时代的 Hadoop 将数据的计算剖析和资源调度进行解耦,独立进去 Yarn 专门负责 CPU、内存、硬盘、网络等资源的调度 HDFS 架构概述NameNode(nn) 存储文件的元数据,如文件名,目录构造,文件属性(生成工夫,正本数,文件权限)以及每个文件的块列表和块所在的 DataNode 等DataNode(dn) 在本地文件系统存储文件块数据,以及块数据的校验和Secondary NameNode(2nn) 监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照YARN 架构概述 ...

January 5, 2021 · 5 min · jiezi

关于redis:redisnginx

Redis大量用户拜访数据库会造成宕机,所以须要redis缓存,加重对数据库的压力。redis长久化策略RDB模式1、RDB是redis默认的策略2、能在肯定的工夫距离主动存储数据:可能导致数据的失落AOF模式1、AOF须要手动开启2、能够设置存储的工夫,容易导致内存占用过大,须要定期维护内存优化LRU算法:依据工夫LFU算法:依据次数随机算法TTL算法:依据残余的存活工夫,超时删除缓存生效缓存穿透(数据缓存中没有数据库中也没有的数据):因为缓存中没有该数据,数据库中也没有该数据,大量用户拜访数据库导致数据库宕机。缓存击穿(数据缓存中没有数据库中有的数据):因为缓存中没有该数据,大量用户间接拜访数据库,导致数据库压力过大。缓存雪崩:大量的数据大批量过期,大量的用户间接拜访数据库,从而导致数据库压力过大。存穿透:设置IP限流,微服务熔断器缓存击穿:设置多级缓存缓存雪崩:设置多级缓存redis分片扩容redis哨兵当一台服务器宕机,通过心跳机制从新选举一台当作主机redis集群实现高可用Nginx正向代理用户拜访服务器,用户拜访服务器A,依据服务器A拜访服务器B,服务器不晓得实在的拜访地址。反向代理用户拜访服务器,用户拜访服务器A,依据nginx转载到服务器B,用户不晓得实在的拜访地址。负载平衡用户拜访服务器A,依据nginx反向代理转载到服务器B,加重对一台服务器的压力,从而加重对服务器的压力。轮询策略权重策略IPHASH策略

January 3, 2021 · 1 min · jiezi

关于redis:深入学习Redis之缓存设计与优化

缓存的应用与设计缓存的收益与老本收益: 减速读写:CPU L1/L2/L3 Cache、浏览器缓存等。因为缓存通常都是全内存的(例如 Redis、Memcache),而 存储层通常读写性能不够强悍(例如 MySQL),通过缓存的应用能够无效 地减速读写,优化用户体验。升高后端负载:帮忙后端缩小访问量和简单计算,在很大水平升高了后端的负载。老本: 数据不统一:缓存层和数据层有工夫窗口不统一,和更新策略无关。代码保护老本:退出缓存后,须要同时解决缓存层和存储层的逻辑, 增大了开发者保护代码的老本。运维老本:以 Redis Cluster 为例,退出后无形中减少了运维老本。应用场景: 升高后端负载:对高耗费的 SQL:join 后果集/分组统计后果缓存。减速申请响应:利用 Redis/Memcache 优化 IO 响应工夫。大量写合并为批量写:比方计数器先 Redis 累加再批量写入 DB。缓存更新策略缓存中的数据通常都是有生命周期的,须要在指定工夫后被删除或更新,这样能够保障缓存空间在一个可控的范畴。 然而缓存中的数据会和数据源中的实在数据有一段时间窗口的不统一,须要利用某些策略进行更新。 上面将别离从应用场景、一致性、开发人员开发/保护老本三个方面介绍三种缓存的更新策略。 LRU/LFU/FIFO 算法剔除LRU:Least Recently Used,最近起码应用。 LFU:Least Frequently Used,最不常常应用。 FIFO:First In First Out,先进先出。 应用场景:剔除算法通常用于缓存使用量超过了预设的最大值时候,如何对现有的数据进行剔除。例如 Redis 应用maxmemory-policy这个配置作为内存最大值后对于数据的剔除策略。 一致性:要清理哪些数据是由具体算法决定,开发人员只能决定应用哪种算法,所以数据的一致性是最差的。 保护老本:算法不须要开发人员本人来实现,通常只须要配置最大maxmemory和对应的策略即可。 超时剔除应用场景:超时剔除通过给缓存数据设置过期工夫,让其在过期工夫后主动删除,例如 Redis 提供的 expire 命令。如果业务能够容忍一段时间内,缓存层数据和存储层数据不统一,那么能够为其设置过期工夫。在数据过期后,再从实在数据源获取数据,从新放到缓存并设置过期工夫。 一致性:一段时间窗口内(取决于过期工夫长短)存在一致性问题,即缓存数据和实在数据源的数据不统一。 保护老本:保护老本不是很高,只需设置 expire 过期工夫即可,当然前提是利用方容许这段时间可能产生的数据不统一。 被动更新应用场景:利用方对于数据的一致性要求高,须要在实在数据更新后, 立刻更新缓存数据。例如能够利用音讯零碎或者其余形式告诉缓存更新。 一致性:一致性最高,但如果被动更新产生了问题,那么这条数据很可能很长时间不会更新,所以倡议联合超时剔除一起应用成果会更好。 保护老本:保护老本会比拟高,开发者须要本人来实现更新,并保障更新操作的正确性。 总结策略一致性保护老本LRU/LFU/FIFO最差低超时剔除较差低被动更新最好高倡议: 低一致性业务倡议配置最大内存和淘汰策略的形式应用。高一致性业务能够联合应用超时剔除和被动更新,这样即便被动更新出了问题,也能保证数据过期工夫后删除脏数据。缓存粒度管制个别罕用的架构就是缓存层应用 Redis,存储层应用 MySQL。 比方:咱们当初须要缓存用户信息。 第一步:从 MySQL 查问,失去后果。 第二步:放入缓存中。 然而,咱们是缓存 MySQL 查出的所有列呢,还是某一些比拟重要罕用的列。 ...

January 2, 2021 · 2 min · jiezi

关于redis:总结一波-Redis-面试题收藏起来

本文的面试题如下: Redis 长久化机制缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题热点数据和冷数据是什么Memcache与Redis的区别都有哪些?单线程的redis为什么这么快redis的数据类型,以及每种数据类型的应用场景,Redis 内部结构redis的过期策略以及内存淘汰机制【~】Redis 为什么是单线程的,长处如何解决redis的并发竞争key问题Redis 集群计划应该怎么做?都有哪些计划?有没有尝试进行多机redis 的部署?如何保证数据统一的?对于大量的申请怎么样解决Redis 常见性能问题和解决方案?解说下Redis线程模型为什么Redis的操作是原子性的,怎么保障原子性的?Redis事务Redis实现分布式锁Redis 长久化机制 Redis是一个反对长久化的内存数据库,通过长久化机制把内存中的数据同步到硬盘文件来保证数据长久化。当Redis重启后通过把硬盘文件从新加载到内存,就能达到复原数据的目标。 实现:独自创立fork()一个子过程,将以后父过程的数据库数据复制到子过程的内存中,而后由子过程写入到临时文件中,长久化的过程完结了,再用这个临时文件替换上次的快照文件,而后子过程退出,内存开释。 RDB是Redis默认的长久化形式。依照肯定的工夫周期策略把内存的数据以快照的模式保留到硬盘的二进制文件。即Snapshot快照存储,对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。( 快照能够是其所示意的数据的一个正本,也能够是数据的一个复制品。)AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最初,相似于MySQL的binlog。当Redis重启是会通过从新执行文件中保留的写命令来在内存中重建整个数据库的内容。 当两种形式同时开启时,数据恢复Redis会优先选择AOF复原。 对了,我把公布过的 Redis 相干的文章整顿成了 PDF,关注微信公众号 Java后端,回复 666 下载这本 Java技术栈手册。 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题 缓存雪崩缓存雪崩咱们能够简略的了解为:因为原有缓存生效,新缓存未到期间 (例如:咱们设置缓存时采纳了雷同的过期工夫,在同一时刻呈现大面积的缓存过期),所有本来应该拜访缓存的申请都去查询数据库了,而对数据库CPU和内存造成微小压力,重大的会造成数据库宕机。从而造成一系列连锁反应,造成整个零碎解体。 解决办法:大多数零碎设计者思考用加锁( 最多的解决方案)或者队列的形式保障来保障不会有大量的线程对数据库一次性进行读写,从而防止生效时大量的并发申请落到底层存储系统上。还有一个简略计划就时讲缓存生效工夫扩散开。 缓存穿透缓存穿透是指用户查问数据,在数据库没有,天然在缓存中也不会有。这样就导致用户查问的时候,在缓存中找不到,每次都要去数据库再查问一遍,而后返回空(相当于进行了两次无用的查问)。这样申请就绕过缓存间接查数据库,这也是常常提的缓存命中率问题。 解决办法:最常见的则是采纳布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个肯定不存在的数据会被这个bitmap拦挡掉,从而防止了对底层存储系统的查问压力。 另外也有一个更为简略粗犷的办法,如果一个查问返回的数据为空(不论是数据不存在,还是系统故障),咱们依然把这个空后果进行缓存,但它的过期工夫会很短,最长不超过五分钟。通过这个间接设置的默认值寄存到缓存,这样第二次到缓冲中获取就有值了,而不会持续拜访数据库,这种方法最简略粗犷。 5TB的硬盘上放满了数据,请写一个算法将这些数据进行排重。如果这些数据是一些32bit大小的数据该如何解决?如果是64bit的呢? 对于空间的利用达到了一种极致,那就是Bitmap和布隆过滤器(Bloom Filter)。 Bitmap:典型的就是哈希表 毛病是,Bitmap对于每个元素只能记录1bit信息,如果还想实现额定的性能,恐怕只能靠就义更多的空间、工夫来实现了。 布隆过滤器(举荐) 就是引入了k(k>1)k(k>1)个互相独立的哈希函数,保障在给定的空间、误判率下,实现元素判重的过程。 它的长处是空间效率和查问工夫都远远超过个别的算法,毛病是有肯定的误识别率和删除艰难。 Bloom-Filter算法的核心思想就是利用多个不同的Hash函数来解决“抵触”。 Hash存在一个抵触(碰撞)的问题,用同一个Hash失去的两个URL的值有可能雷同。为了缩小抵触,咱们能够多引入几个Hash,如果通过其中的一个Hash值咱们得出某元素不在汇合中,那么该元素必定不在汇合中。只有在所有的Hash函数通知咱们该元素在汇合中时,能力确定该元素存在于汇合中。这便是Bloom-Filter的根本思维。 Bloom-Filter个别用于在大数据量的汇合中断定某元素是否存在。 缓存穿透与缓存击穿的区别缓存击穿:是指一个key十分热点,在不停的扛着大并发,大并发集中对这一个点进行拜访,当这个key在生效的霎时,继续的大并发就穿破缓存,间接申请数据。 解决方案:在拜访key之前,采纳SETNX(set if not exists)来设置另一个短期key来锁住以后key的拜访,拜访完结再删除该短期key。 给一个我公司解决的案例:背景双机拿token,token在存一份到redis,保证系统在token过期时都只有一个线程去获取token;线上环境有两台机器,故应用分布式锁实现。 三、缓存预热 缓存预热这个应该是一个比拟常见的概念,置信很多小伙伴都应该能够很容易的了解,缓存预热就是零碎上线后,将相干的缓存数据间接加载到缓存零碎。这样就能够防止在用户申请的时候,先查询数据库,而后再将数据缓存的问题!用户间接查问当时被预热的缓存数据! 解决思路: 间接写个缓存刷新页面,上线时手工操作下;数据量不大,能够在我的项目启动的时候主动进行加载;定时刷新缓存;四、缓存更新 除了缓存服务器自带的缓存生效策略之外(Redis默认的有6中策略可供选择),咱们还能够依据具体的业务需要进行自定义的缓存淘汰,常见的策略有两种: 定时去清理过期的缓存;当有用户申请过去时,再判断这个申请所用到的缓存是否过期,过期的话就去底层零碎失去新数据并更新缓存。两者各有优劣,第一种的毛病是保护大量缓存的key是比拟麻烦的,第二种的毛病就是每次用户申请过去都要判断缓存生效,逻辑绝对比较复杂!具体用哪种计划,大家能够依据本人的利用场景来衡量。 五、缓存降级 当访问量剧增、服务呈现问题(如响应工夫慢或不响应)或非核心服务影响到外围流程的性能时,依然须要保障服务还是可用的,即便是有损服务。零碎能够依据一些要害数据进行主动降级,也能够配置开关实现人工降级。 降级的最终目标是保障外围服务可用,即便是有损的。而且有些服务是无奈降级的(如退出购物车、结算)。 以参考日志级别设置预案: 个别:比方有些服务偶然因为网络抖动或者服务正在上线而超时,能够主动降级;正告:有些服务在一段时间内成功率有稳定(如在95~100%之间),能够主动降级或人工降级,并发送告警;谬误:比方可用率低于90%,或者数据库连接池被打爆了,或者访问量忽然猛增到零碎能接受的最大阀值,此时能够依据状况主动降级或者人工降级;严重错误:比方因为非凡起因数据谬误了,此时须要紧急人工降级。服务降级的目标,是为了避免Redis服务故障,导致数据库跟着一起产生雪崩问题。因而,对于不重要的缓存数据,能够采取服务降级策略,例如一个比拟常见的做法就是,Redis呈现问题,不去数据库查问,而是间接返回默认值给用户。 热点数据和冷数据是什么 热点数据,缓存才有价值 对于冷数据而言,大部分数据可能还没有再次拜访到就曾经被挤出内存,不仅占用内存,而且价值不大。频繁批改的数据,看状况思考应用缓存 对于下面两个例子,寿星列表、导航信息都存在一个特点,就是信息批改频率不高,读取通常十分高的场景。 对于热点数据,比方咱们的某IM产品,生日祝愿模块,当天的寿星列表,缓存当前可能读取数十万次。再举个例子,某导航产品,咱们将导航信息,缓存当前可能读取数百万次。 数据更新前至多读取两次, 缓存才有意义。这个是最根本的策略,如果缓存还没有起作用就生效了,那就没有太大价值了。 那存不存在,批改频率很高,然而又不得不思考缓存的场景呢?有!比方,这个读取接口对数据库的压力很大,然而又是热点数据,这个时候就须要思考通过缓存伎俩,缩小数据库的压力,比方咱们的某助手产品的,点赞数,珍藏数,分享数等是十分典型的热点数据,然而又一直变动,此时就须要将数据同步保留到Redis缓存,缩小数据库压力。 ...

December 30, 2020 · 2 min · jiezi

关于redis:微信附近的人用redis也能实现GEO

置信微信左近的人的性能大家都应该用过我能够很随便的通过我本人的定位能看到我左近的人,并且能看到那个人间隔我的间隔,大家有没有思考过这个是怎么实现的? 作为一个程序猿任何问题应该都有一个思考的过程,而不是间接看论断,接下来大家一步一步的思考,直到问题解决。 获取本人的地位左近的人其实就是一种地位的比对关系,所以第一步是得获取本人的地位,个别地位都是用经纬度来示意,具体经纬度的获取得依赖客户端,作为咱们后端程序员间接接管参数就能够了,所以这一步重点是用经纬度来示意各个节点的地位,对经纬度不是很理解的敌人能够温习一下中学的地理知识。 用关系型数据库(mysql)的形式解决问题咱们先把问题简化,如果我左近的人都是不动的,也就是说他们的地位是固定的,依照咱们传统的思路,就是把每个人的经纬度存起来,而后遍历这些经纬度,咱们能够通过某种办法获取我和各个经纬度之间的间隔,而后把绝对于我间隔在 5km 以内的用户展现进去就能够了 具体实现如下把每个人的经纬度存起来,存储如下user_idlongitude(经度)latitude(纬度)1116.3939.912121.4831.43117.3039.71.........遍历数据,和本人比照,取得每个人和本人的间隔把数据库的所有记录都遍历一遍,把每一条记录的经纬度和本人的经纬度做个比照,就能获取到各个记录离本人的间隔。 如何依据两个经纬度,获取到这两个点之间的间隔我在网上招了个办法,大家能够参考下 /** * 求两个已知经纬度之间的间隔,单位为米 * * @param lng1 $ ,lng2 经度 * @param lat1 $ ,lat2 纬度 * @return float 间隔,单位米 * @author www.Alixixi.com */function getdistance($lng1, $lat1, $lng2, $lat2) { // 将角度转为狐度 $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度 $radLat2 = deg2rad($lat2); $radLng1 = deg2rad($lng1); $radLng2 = deg2rad($lng2); $a = $radLat1 - $radLat2; $b = $radLng1 - $radLng2; $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000; return $s;}筛选出间隔和本人在 5km 以内的数据就是咱们想得到的后果把上次算进去的间隔一一比照,在 5km 以内的数据就是咱们须要的左近的人的数据。 ...

December 30, 2020 · 2 min · jiezi

关于redis:Redis-低成本高可用方案设计

对于Redis高可用计划,看到较多的是keepalived、zookeeper计划。keepalived是主备模式,意味着总有一台节约着。zookeeper工作量老本偏高。 本文次要介绍下应用官网sentinel做redis高可用计划的设计。 Sentinel介绍Sentinel是Redis官网为集群提供的高可用解决方案。在理论我的项目中能够应用sentinel去做redis主动故障转移,缩小人工染指的工作量。另外sentinel也给客户端提供了监控音讯的告诉,这样客户端就可依据音讯类型去判断服务器的状态,去做对应的适配操作。 上面是Sentinel次要性能列表: Monitoring:Sentinel继续查看集群中的master、slave状态,判断是否存活。Notification:在发现某个redis实例死的状况下,Sentinel能通过API告诉系统管理员或其余程序脚本。Automatic failover:如果一个master挂掉后,sentinel立马启动故障转移,把某个slave晋升为master。其余的slave重新配置指向新master。Configuration provider:对于客户端来说sentinel告诉是无效可信赖的。客户端会连贯sentinel去申请以后master的地址,一旦产生故障sentinel会提供新地址给客户端。Sentinel配置Sentinel实质上只是一个运行在非凡模式下的redis服务器,通过不同配置来辨别提供服务。sentinel.conf配置: // [监控名称] [ip] [port] [多少sentinel批准才产生故障转移]sentinel monitor mymaster 127.0.0.1 6379 2// [监控名称] [Master多少毫秒后不回应ping命令,就认为master是主观下线状态]sentinel down-after-milliseconds mymaster 60000// [故障转移超时工夫]sentinel failover-timeout mymaster 180000//[在执行故障转移时,最多能够有多少个从服务器同时对新的主服务器进行同步]sentinel parallel-syncs mymaster 1sentinel须要应用redis2.8版本以上,启动如下: redis-sentinel sentinel.conf启动后Sentinel会: 以10秒一次的频率,向被监督的master发送info命令,依据回复获取master以后信息。以1秒一次的频率,向所有redis服务器、蕴含sentinel在内发送PING命令,通过回复判断服务器是否在线。以2秒一次的频率,通过向所有被监督的master,slave服务器发送蕴含以后sentinel,master信息的音讯。另外倡议sentinel至多起3个实例以上,并配置2个实例批准即可产生转移。5个实例,配置3个实例批准以此类推。学会这15点,让你分分钟拿下Redis数据库故障转移音讯接管的3种形式Redis服务器一旦发送故障后,sentinel通过raft算法投票选举新master。故障转移过程能够通过sentinel的API获取/订阅接管事件音讯。 脚本接管 当故障转移期间,能够指定一个“告诉”脚本用来告知系统管理员,以后集群的状况。脚本被容许执行的最大工夫为60秒,如果超时,脚本将会被终止(KILL)sentinel notification-script mymaster /var/redis/notify.sh 故障转移期之后,配置告诉客户端的脚本.sentinel client-reconfig-script mymaster /var/redis/notifyReconfig.sh 客户端间接接管Sentinel的故障转移音讯告诉应用的是redis公布订阅。就是说在故障转移期间所有产生的事件信息,都通过频道(channel)公布进来。比方咱们加台slave服务器,sentinel监听到后会公布加slave的音讯到"+slave"频道上,客户端只须要订阅"+slave"频道即可接管到对应音讯。 其音讯格局如下: [实例类型] [事件服务器名称] [服务器ip] [服务器端口] @[master名称] [ip] [端口]<instance-type> <name> <ip> <port> @ <master-name> <master-ip> <master-port>告诉音讯格局示例: *          //订阅类型, *即订阅所有事件音讯。-sdown     //音讯类型slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381订阅音讯示例: using (RedisSentinel rs = new RedisSentinel(CurrentNode.Host, CurrentNode.Port))            {                var redisPubSub = new RedisPubSub(node.Host, node.Port);                redisPubSub.OnMessage += OnMessage;                redisPubSub.OnSuccess += (msg) =>{};                redisPubSub.OnUnSubscribe += (obj) =>{};                redisPubSub.OnError = (exception) =>{ };                redisPubSub.PSubscribe("*");            }服务间接接管这种形式在第二种根底上扩大了一层,即利用端不间接订阅sentinel。独自做服务去干这件事件,而后利用端提供API供这个服务回调告诉。这样做的益处在于: 缩小利用端监听失败出错的可能性。利用端由被动方变成被动方,升高耦合。性能进步,轮询变回调。独立成服务可扩展性更高。比方: 1:当前换掉sentinel,咱们只须要动服务即可,利用端无需更改。2:能够在服务内多减少一层守护线程去被动拉取redis状态,这样可确保即便sentinel不失效,也能及时觉察redis状态,并告诉到利用端。当然这种状况很极其,因为sentinel配的也是多节点,同时挂的几率十分小。示例: 利用端提供回调API,在这个API逻辑上来刷新内存中的Redis连贯。 http://127.0.0.1/redis/notify.api独立服务监控到情况后,调用API告诉利用端: httprequest.post("http://127.0.0/redis/notify.api");整体设计举荐应用第三种,其整体流程图如下: 总结各种sentinel告诉音讯类型见官网文档,我的项目中应用的redis客户端在github上 https://github.com/mushroomsi...本文分享了楼主在我的项目中做Redis高可用的教训,心愿对大家有所帮忙。在人力物力满足的状况下还是举荐应用zookeeper计划的。只有三五杆枪的状况下也就退而求其次,利用最小老本满足需要并保留可扩展性。 置信没有最好的架构,只有更适合的架构。http://redis.io/topics/sentinel 作者:蘑菇学生 起源:https://www.cnblogs.com/mushr...

December 30, 2020 · 1 min · jiezi

关于redis:深入学习Redis一

什么是 RedisRedis 是齐全开源的,恪守 BSD 协定,是一个高性能的 key-value 数据库。 Redis 与其余 key - value 缓存产品有以下三个特点: Redis 反对数据的长久化,能够将内存中的数据保留在磁盘中,重启的时候能够再次加载进行应用。Redis 不仅仅反对简略的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。Redis 反对数据的备份,即 master-slave 模式的数据备份。Redis 的个性个性一:速度快官网宣称能够达到:10 万 QPS 数据是存在内存中的。应用 C 语言编写。单线程模型。Redis 速度快的次要起因就是内存 从快到慢顺次是: Register 寄存器L1 Cache 一级缓存L2 Cache 二级缓存Main Memory 主存Local Disk 本地磁盘Remote Disk 近程磁盘类型每秒读写次数随机读写提早拜访带宽内存千万级80ns5GBSSD 盘350000.1-02ms100~300MB机械盘100 左右10ms100MB 左右个性二:长久化Redis 所有数据保留在内存当中,对数据的更新将以异步形式保留到磁盘上。 Redis 反对两种长久化形式: RDBAOF个性三:多种数据结构 另外在 Redis 从 2.2.0 版本开始新增了三种数据结构: Bitmaps 和 HyperLogLog 其实实质上是字符串,并不算是实在的数据结构,而 GEO 实质上有序汇合实现的。 • BitMaps:能够实现对位的操作。能够把 Bitmaps 设想成一个以位为单位数组,数组中的每个单元只能存 0 或者 1,数组的下标在 bitmaps 中叫做偏移量。单个 bitmaps 的最大长度是 512MB,即 2^32 个比特位。 ...

December 29, 2020 · 11 min · jiezi

关于redis:Redis的安装与配置

下载软件包 wget http://download.redis.io/releases/redis-5.0.5.tar.gz编译装置 tar -xzvf redis-5.0.5.tar.gzyum install gcc -y'make MALLOC=libc' OR 'yum install -y jemalloc' //--https://blog.csdn.net/qq_37859539/article/details/83715803cd redis-5.0.5make PREFIX=/data1/srv/redis installcp redis.conf /data1/srv/redis/bin/批改配置文件 [root@bluse /]# cat /etc/redis.conf bind 192.168.1.242 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /data1/srv/redis/bin replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no replica-priority 100 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes requirepass password配置启动服务 ...

December 29, 2020 · 1 min · jiezi

关于redis:Redis-入门实践

1 简介Redis,REmote DIctionary Server,是一个由 Salvatore Sanfilippo 写的 Key-Value 存储系统。 Redis 是一个开源的应用 ANSI C 语言编写、恪守 BSD 协定、反对网络、可基于内存亦可长久化的日志型、Key-Value 数据库,并提供多种语言的API。 它通常被称为数据结构服务器,因为值(Value)能够是字符串(String), 哈希(Map), 列表(list), 汇合(sets)和有序汇合(sorted sets)等类型。 2 装置官网地址: https://redis.io 下载地址: https://github.com/antirez/redis/releases 2.1 Windows装置实现后在装置目录下执行: redis-server.exe redis.windows.conf 2.2 Linux下载,解压缩并编译Redis最新稳固版本: wget http://download.redis.io/releases/redis-5.0.3.tar.gztar xzf redis-5.0.3.tar.gzcd redis-5.0.3make启动Redis服务: cd src./redis-server ../redis.conf 3 配置Redis 的配置文件,Windows 是装置目录的 redis.windows.conf 文件,Linux 是装置目录下的 redis.conf 文件。 在连贯上 Redis 服务后,能够通过 config 命令查看或者编辑配置项。 3.1 查看redis 127.0.0.1:6379> config get ${name}例: 127.0.0.1:6379> config get port1) "port"2) "6379"3.2 编辑redis 127.0.0.1:6379> config set ${name} ${value}例: ...

December 29, 2020 · 9 min · jiezi

关于redis:玩转RedisRedis高级数据结构及核心命令ZSet

《玩转Redis》系列文章 by zxiaofan次要讲述Redis的根底及中高级利用,交叉企业实战案例。本文是《玩转Redis》系列第【3】篇,最新系列文章请返回 公众号 “zxiaofan”(点我点我)查看,或 百度搜寻 “玩转Redis zxiaofan”(点我点我)即可。 最新思维导图原图可分割公众号【zxiaofan】后盾获取。 本文更适宜用于温习总结,浏览》实战》浏览 更有成果哟,次要蕴含以下内容: Sorted Set(有序汇合); Redis根底数据结构及外围命令详见上一篇文章《玩转Redis-Redis根底数据结构及外围命令》,百度或订阅号搜寻zxiaofan即可: String(字符串);List(列表);Set(汇合);Hash(散列);文章思路: 数据结构利用场景及注意事项;数据结构各命令比照剖析;异样对立阐明: error(out of range)导图简写@EOOR; 正数偏移量示意倒数第几,导图简写@LBN(last but number); 1、ZSet利用场景及注意事项1.1、ZSet利用场景 ZSet次要实用于须要 排序(排行榜) 的场景,如: 粉丝列表(按关注工夫排序);学生成绩排名;文章帖子排名;各类榜单(如微博总热榜、分类热榜);1.2、ZSet注意事项ZSet具备唯一性、有序性:相似Java的SortedSet和HashMap的结合体;底层构造:跳跃列表;setvalue惟一;setvalue有score属性,按此排序;score越小排名越靠前最初一个value被移除后,数据结构主动删除,内存被回收;2、ZSet各命令比照剖析概述: ZSet命令反对以下操作类型:减少、统计、查问、删除/弹出;命令中的lex为lexicographical(ordering),示意按字典规定排序;ZSet参数正负无穷大示意:分数(+inf、-inf);字典排序(+、-);2.1、ZSet减少与统计【外围命令】减少【ZADD、ZINCRBY】;统计数量【ZCARD、ZCOUNT、ZLEXCOUNT】;汇合运算【ZUNIONSTORE、ZINTERSTORE】;留神:【ZADD】反对新增、更新数据:XX存在才更新分数;INCR增减分数;【ZINCRBY】increment防止应用浮点数,后果易出错;【ZCARD、ZCOUNT、ZLEXCOUNT】统计汇合(所有、指定分数区间、指定元素区间)元素个数;【ZUNIONSTORE、ZINTERSTORE】多个汇合并集、交加运算;【Redis-ZSet减少与统计元素操作】命令简述:命令性能参数ZADD增加元素及分数到有序汇合key [NX\XX] [CH] [INCR] score member [score member ...]ZINCRBY减少/缩小分数key increment memberZCARD统计有序汇合的元素个数keyZCOUNT统计指定【score区间】的元素个数key min maxZLEXCOUNT统计指定【元素区间】的元素个数key min maxZINTERSTORE计算指定有序集的【交加】并将后果存入指标汇合destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM\MIN\MAX]ZUNIONSTORE计算指定有序集的【并集】并将后果存入指标汇合destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM\MIN\MAX]【Redis-ZSet减少与统计元素操作】命令具体比照剖析如下: 【ZINCRBY】命令示例:# 【ZINCRBY】命令示例 @zxiaofan127.0.0.1:6378> zincrby zset2 2 m"2"127.0.0.1:6378> zincrby zset2 2.2 m"4.2000000000000002"【ZUNIONSTORE】命令示例:# 【ZUNIONSTORE】命令示例 @zxiaofan127.0.0.1:6378> zadd zset1 1 a 2 b 2 c 3 d(integer) 4127.0.0.1:6378> zadd zset2 2 a 3 b(integer) 2127.0.0.1:6378> zunionstore outset 2 zset1 zset2 weights 1 3(integer) 4127.0.0.1:6378> zrange outset 0 -1 withscores1) "c"2) "2"3) "d"4) "3"5) "a"6) "7"7) "b"8) "11"127.0.0.1:6378> zunionstore outset 2 zset1 zset2 weights 1 3.5(integer) 4127.0.0.1:6378> zrange outset 0 -1 withscores1) "c"2) "2"3) "d"4) "3"5) "a"6) "8"7) "b"8) "12.5"127.0.0.1:6378> zunionstore outset 2 zset1 zset2 weights 2(error) ERR syntax error127.0.0.1:6378> zunionstore outset 2 zset1 zset2 weights 1 3 AGGREGATE MIN(integer) 4127.0.0.1:6378> zrange outset 0 -1 withscores1) "a"2) "1"3) "b"4) "2"5) "c"6) "2"7) "d"8) "3"127.0.0.1:6378> zunionstore outset 2 zset1 zset2 weights 1 3 AGGREGATE MAX(integer) 4127.0.0.1:6378> zrange outset 0 -1 withscores1) "c"2) "2"3) "d"4) "3"5) "a"6) "6"7) "b"8) "9"2.2、ZSe查问【外围命令】查问分数【ZSCORE】;查问排名【ZRANK、ZREVRANK】;按排名排序查问【ZRANGE、ZREVRANGE】;按字典程序排序查问【ZRANGEBYLEX、ZREVRANGEBYLEX】;按分数排序查问【ZRANGEBYSCORE、ZREVRANGEBYSCORE】;分页迭代【ZSCAN】;留神:【ZSCORE】可用于判断汇合中是否存在某元素;【ZRANK、ZREVRANK】查问排名 ...

December 26, 2020 · 3 min · jiezi

关于redis:Redis2020最新简易图文教程下内含学习视频

SpringDataRedis创立我的项目 增加依赖<dependencies> <!-- spring data redis 组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- commons-pool2 对象池依赖 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- web 组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- test 组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies>增加application.yml配置文件spring: redis: # Redis服务器地址 host: 192.168.10.100 # Redis服务器端口 port: 6379 # Redis服务器端口 password: root # Redis服务器端口 database: 0 # 连贯超时工夫 timeout: 10000ms jedis: pool: # 最大连接数,默认8 max-active: 1024 # 最大连贯阻塞等待时间,单位毫秒,默认-1ms max-wait: 10000ms # 最大闲暇连贯,默认8 max-idle: 200 # 最小闲暇连贯,默认0 min-idle: 5Lettuce和Jedis的区别 Jedis 是一个优良的基于 Java 语言的 Redis 客户端,然而,其有余也很显著:Jedis 在实现上是间接连贯 Redis-Server,在多个线程间共享一个 Jedis 实例时是线程不平安的,如果想要在多线程场景下应用 Jedis,须要应用连接池,每个线程都应用本人的 Jedis实例,当连贯数量增多时,会耗费较多的物理资源。 ...

December 24, 2020 · 4 min · jiezi

关于redis:太厉害了目前-Redis-可视化工具最全的横向评测

1. 命令行不晓得大家在日常操作redis时用什么可视化工具呢? 以前总感觉没有什么太好的可视化工具,于是问了一个业内敌人。对方回:你还用可视化工具?间接命令行呀,redis提供了这么多命令,操作起来行云流水。用可视化工具感觉很low。 命令行的鄙视用工具的,用高端工具的鄙视低端工具的,鄙视链始终存在。尽管用命令行本人也能够,然而总感觉效率上不如用工具,在视觉上不那么直观。尤其是看json的时候,在命令行就很不敌对。 大佬敌人说:谁说命令行就不能格式化json了?能够利用iredis,用|将redis通过pipe用shell的其余工具,比方jq/fx/rg/sort/uniq/cut/sed/awk等解决。还能主动补全,高亮显示,性能很多 好吧 ,的确牛逼。附上这个工具的官网地址,喜爱用命令行的敌人能够去试一试,相对能让喜爱命令行的你爽的飞起来。 https://iredis.io/然而我置信大多数开发者还是习惯用可视化工具。我本人也用过不少redis的可视化工具。明天就细数下市面上风行的各个可视化的工具的优劣势。帮忙你找到最好的redis可视化工具。晋升debug效率。 如果你想间接看最终总结,能够间接拉到文章的开端。 2. 可视化工具分类依照redis可视化工具的部署来分,能够分成3大类 桌面客户端版web版IDE工具的plugin桌面版这次评测的软件如下: redis desktop managermedisAnotherRedisDesktopManagerfastoredisredis-plusredWeb版本评测的软件如下: redis-insightIDE插件版本,这里只评测IntelliJ IDEA的插件,eclipse的就不作介绍了 Iedis23. Redis Desktop Manager这个工具应该是当初使用率最广的可视化工具了。存在工夫很久。通过了数次迭代。跨平台反对。以前是收费的,当初为免费工具。试用能够有半个月的工夫。链接为: https://redisdesktop.com/ 评测: 之前用感觉性能还行,就是界面UI丑了点。最近下了最新版,感觉通过了那么长时间迭代,界面看着也还对付。该有的性能都有。界面看着比拟简洁,性能很全。 key的显示能够反对按冒号宰割的键名空间,除了根本的五大数据类型之外,还反对redis 5.0新出的Stream数据类型。在value的显示方面。反对多达9种的数据显示方式。 命令行模式也同以前有了很大的提高,反对了命令主动提醒。 从性能看上去中规中矩,应用起来便捷。最大的毛病就是不收费。集体应用的话,大略一年要200多RMB的价格。 - 4.medis现阶段我使用率最高的redis可视化工具。界面合乎集体审美。布局简洁。跨平台反对,要害是收费。链接为: http://getmedis.com/ 评测: 颜值挺高,性能合乎日常应用要求。对key有色彩显明的图标标识。在key的搜寻上挺不便的,能够含糊搜寻出匹配的key,渐进式的scan,无显著卡顿。在搜寻的体验上还是比拟杰出的。 毛病是不反对key的命名空间展现,不反对redis 5.0的stream数据类型,命令行比拟繁多,不反对主动匹配和提醒。反对的value的展示形式也只有3种 - 5.AnotherRedisDesktopManager一款比较稳定简洁的redis UI工具。链接为: https://github.com/qishibo/An... 评测: 很中规中矩的一款收费的redis可视化工具,根本的性能都有。有监控统计,反对暗黑主题,还反对集群的增加。 毛病是没什么亮点,UI很简略,不反对stream数据类型。命令行模式也比拟繁多。value展现反对的类型也只有3种。 - 6.FastoRedisFastoRedis之前没听到过。而后去下了体验了下。 应用这款工具首先得去官网注册账号。这款软件是免费软件,尽管跨平台,然而试用只有一天的工夫。链接为: https://fastoredis.com/ 评测: 毕竟是免费软件,尽管界面一股浓浓的windows格调,乍看上去有点像redis desktop manager,然而就性能而言。的确不错,反对了集群模式和哨兵模式,key的命名空间展现,redis 5.0的stream数据类型也反对。 命令行模式反对主动提醒补全 value的显示反对树状,表格状等等显示方式。令我诧异的是,值对象反对多达17种渲染形式 总的来说,除了界面UI交互略僵硬,还有是一款免费软件之外,还是一款很不错的redis可视化工具。 - 7.RedisPlus一款开源的收费桌面客户端软件链接: https://gitee.com/MaxBill/Red... 评测: 没什么亮点,也就基本功能。加分项可能也就是有一个监控。其余的都很一般 。甚至于这款软件连命令行模式都没有。用的是javafx开发,按道理说,应该是跨平台的软件 ,然而提供的下载地址,并没有mac的间接安装包。况且就算是跨平台的吧。 ...

December 23, 2020 · 1 min · jiezi

关于redis:jedis源码分析写数据

调用栈sendCommand:100, Protocol (redis.clients.jedis) //发送命令到redis服务器sendCommand:85, Protocol (redis.clients.jedis)sendCommand:115, Connection (redis.clients.jedis)set:133, BinaryClient (redis.clients.jedis)set:58, Client (redis.clients.jedis)set:153, Jedis (redis.clients.jedis) //写数据redisDSTest:16, RedisDSTest (cn.hutool.db.nosql) //利用类-入口invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)invoke:566, Method (java.lang.reflect)runReflectiveCall:59, FrameworkMethod$1 (org.junit.runners.model)run:12, ReflectiveCallable (org.junit.internal.runners.model)invokeExplosively:56, FrameworkMethod (org.junit.runners.model)evaluate:17, InvokeMethod (org.junit.internal.runners.statements)evaluate:306, ParentRunner$3 (org.junit.runners)evaluate:100, BlockJUnit4ClassRunner$1 (org.junit.runners)runLeaf:366, ParentRunner (org.junit.runners)runChild:103, BlockJUnit4ClassRunner (org.junit.runners)runChild:63, BlockJUnit4ClassRunner (org.junit.runners)run:331, ParentRunner$4 (org.junit.runners)schedule:79, ParentRunner$1 (org.junit.runners)runChildren:329, ParentRunner (org.junit.runners)access$100:66, ParentRunner (org.junit.runners)evaluate:293, ParentRunner$2 (org.junit.runners)evaluate:306, ParentRunner$3 (org.junit.runners)run:413, ParentRunner (org.junit.runners)run:137, JUnitCore (org.junit.runner)startRunnerWithArgs:68, JUnit4IdeaTestRunner (com.intellij.junit4)startRunnerWithArgs:33, IdeaTestRunner$Repeater (com.intellij.rt.junit)prepareStreamsAndStart:230, JUnitStarter (com.intellij.rt.junit)main:58, JUnitStarter (com.intellij.rt.junit) ...

December 20, 2020 · 2 min · jiezi

关于redis:redis键值对用什么结构组织

redis键值对用什么构造组织?一个全局哈希表(数组),由多个哈希桶(数组上的元素,蕴含entry元素)组成 比方,键名: aaa,键值 : bbb 通过hash(aaa), 失去数组下标6,则哈希桶6。哈希桶6中的entry元素蕴含key和value指针, key指向键名aaa, value指向键值bbb, 而bbb就是咱们平时业务接触过的罕用redis数据结构,string,list等 redis存储数据太多,为什么查找速率会变慢?哈希桶数量无效,key通常会比哈希桶多,多个key可能落在同一哈希桶,则哈希抵触(哈希抵触:两个key的哈希值和哈希桶的计算关系中,落在同一个哈希桶。),所以先要找到桶,再找桶上的元素,所以变慢了 同一个哈希桶的元素是如何存储的?如图,同一个哈希桶的多个元素(entry1,entry2等)以链表保留,顺次用指针链接,entry1 元素会通过一个next指针指向 entry2,同样,entry2 也会通过next指针指向 entry3,此链表称为哈希抵触链 找到哈希桶后,redis如何查找到对应元素?沿着链表指针指向查找,判断entry元素中*key指针指向的键名是否统一 当数据越来越多,哈希抵触链太长,查找元素变慢怎么办?rehash(再哈希),减少现有哈希桶,让entry元素扩散在不同哈希桶中,缩小单通元素数量。默认有两个哈希表,则哈希表1,哈希表2。rehash过程如下。 给哈希表 2 调配更大的空间,例如是以后哈希表 1 大小的两倍把哈希表 1 中的数据从新映射并拷贝到哈希表 2 中开释哈希表 1 的空间。哈表1数据太多,一次性拷贝到哈希表2工夫太长,阻塞线程,影响redis失常服务怎么办?渐进式rehash,在下面第二步过程中,有一个客户端申请,就把哈希表1索引1的元素先迁徙过来再有一个申请,再把哈希表索引2的元素迁徙,这样就防止了全量拷贝阻塞线程影响服务。

December 18, 2020 · 1 min · jiezi

关于redis:虚拟机搭建1主1从redis主从集群搭建

场景redis作为以后煊赫一时的NOSQL零碎,自身就反对主从集群,基于虚拟机入手搭建一个1主1从的redis集群(哨兵模式)。redis集群(redis cluster)次要是解决单机数据存储问题,redis集群将数据分布式存储与多台机器上。然而很多状况下,在小用户公司机器不容许的状况下,咱们多采纳redis主从-哨兵模式。 搭建1、环境筹备这里应用2台服务器,每台服务器上开启一个redis-server和redis-sentinel服务,redis-server端口为7001,redis-sentinel的端口为6001。 redis-server阐明 192.168.1.110:7001 主192.168.1.111:7001 从redis-sentinel阐明 192.168.1.110:6001192.168.1.111:60012、搭建redis零碎先在三台机器上装置redis,具体步骤可参考虚拟机-搭建3主3从redis集群 装置实现后复制redis提供的默认配置文件 cp /usr/src/redis-4.0.1/redis.conf /usr/local/redis批改配置文件 cd /usr/local/redis vim redis.conf 主节点192.168.1.110上的配置 bind 192.168.1.100 //(留神:bind的意思不是绑定内部服务器的IP,而是绑定本机能够承受拜访的IP)port 7001 daemonize yes //后盾过程requirepass 123456pidfile redis_7001.pid loglevel noticelogfile "/usr/local/redis/redis_7001.log" //日志文件寄存目录 dir /usr/local/redis/ //节点主目录寄存地位 appendonly yesdbfilename dump.rdbappendfilename "appendonly.aof"appendfsync everysec从节点192.168.1.111上的配置 bind 192.168.1.111 //(留神:bind的意思不是绑定内部服务器的IP,而是绑定本机能够承受拜访的IP)port 7001 daemonize yes //后盾过程requirepass 123456pidfile redis_7001.pid loglevel noticelogfile "/usr/local/redis/redis_7001.log" //日志文件寄存目录 dir /usr/local/redis/ //节点主目录寄存地位 #额定补充masterauth 123456slaveof 192.168.1.110 7001appendonly yesdbfilename dump.rdbappendfilename "appendonly.aof"appendfsync everysec启动2台机器: ./bin/redis-server ./redis.confedis服务启动结束后,进入命令行,执行info replication查看以后主从配置 ...

December 18, 2020 · 1 min · jiezi

关于redis:GeoHash原理及redis-geo相关操作

geohash计算原理经纬度地图:纵线是经度(-180~180)横线为纬度(-90~90) GeoHash是一种地址编码方法。他可能把二维的空间经纬度数据编码成一个二进制字符串,而后base32后成为一个短字符串。以(123.15488794512, 39.6584212421)为例计算geohash: 1、第一步,经纬度别离计算出一个二进制数,通过二分法一直查找最小区间。 以经度123.15488794512为例,计算过程如下: 精度左边界平均值右边界后果1-18001801209018013901351800490112.513515112.5123.7513506112.5118.125123.7517118.125120.9375123.7518120.9375122.3438123.7519122.3438123.0469123.75110123.0469123.3984123.75011123.0469123.2227123.3984012123.0469123.1348123.2227113123.1348123.1787123.2227014123.1348123.1567123.1787015123.1348123.1458123.1567116123.1458123.1512123.1567117123.1512123.154123.1567118123.154123.1554123.1567019123.154123.1547123.1554120123.1547123.155123.15540#经度转换后果11010111100100111010#维度转换后果101110000110011100112、两个二进制组合,经度占偶数位,纬度占奇数位 11100 11101 10101 01001 01100 00111 11100 01101#8个10进制数28 29 21 9 12 7 28 13wxp9d7we3、每5位一组,进行base32编码 base32编码参照 public static function geoHash($lon, $lat, $precision = 10) { $lonA = ''; $s = -180;$t = 180; $totalBits = $precision * 5; $bits = ceil($totalBits / 2); for ($i = 0; $i < $bits; $i++) { $mid = ($s + $t) / 2; if ($lon >= $mid) { $lonA .= 1; $s = $mid; } else { $t = $mid; $lonA .= 0; } } $latA = ''; $s = -90;$t = 90; $bits = floor($totalBits / 2); for ($i = 0; $i < $bits; $i++) { $mid = ($s + $t) / 2; if ($lat >= $mid) { $latA .= 1; $s = $mid; } else { $t = $mid; $latA .= 0; } } $geoBinary = ''; for ($i = 0; $i < $bits; $i++) { $geoBinary .= $lonA[$i] . $latA[$i]; } return self::base32Encode($geoBinary, $totalBits);} public static function decodeGeoHash(string $geohash) { $geoBinary = self::base32Decode($geohash); $lonS = -180;$lonT = 180; $latS = -90;$latT = 90; for ($i = 0; $i < strlen($geoBinary); $i += 2) { $lonCode = $geoBinary[$i]; $lonMid = ($lonS + $lonT) / 2; if ($lonCode) { $lonS = $lonMid; } else { $lonT = $lonMid; } $latCode = $geoBinary[$i + 1]; $latMid = ($latS + $latT) / 2; if ($latCode) { $latS = $latMid; } else { $latT = $latMid; } } $geo = [($lonS + $lonT) / 2, ($latS + $latT) / 2]; return $geo;} public static function base32Encode(string $geoBinary, $bits){ $encodeMap = '0123456789bcdefghjkmnpqrstuvwxyz'; $encode = ''; for ($i = 0; $i < $bits; $i += 5) { $digit = intval(substr($geoBinary, $i, 5), 2); $encode .= $encodeMap[$digit]; } return $encode;} public static function base32Decode(string $geoHash){ $encodeMap = '0123456789bcdefghjkmnpqrstuvwxyz'; $decode = ''; for ($i = 0; $i < strlen($geoHash); $i++) { $digit = strpos($encodeMap, $geoHash[$i]); $binary = base_convert($digit, 10, 2); $decode .= sprintf('%05d', $binary); } return $decode;} public function testGeoHash(){ $geohash = self::geoHash(123.15488794512, 39.6584212421, 10);//wxp9d7wehc $geo = self::decodeGeoHash($geohash);// (123.15488755703, 39.658420979977)}geohash的应用geohash的位数是9位数的时候,误差约为4米;geohash的位数是10位数的时候,误差为0.6米 ...

December 18, 2020 · 2 min · jiezi

关于redis:深度图解Redis-Cluster原理

不想谈好吉他的撸铁狗,不是好的程序员,欢送微信关注「SH的全栈笔记」前言上文咱们聊了基于Sentinel的Redis高可用架构,理解了Redis基于读写拆散的主从架构,同时也晓得当Redis的master产生故障之后,Sentinel集群是如何执行failover的,以及其执行failover的原理是什么。 这里大略再提一下,Sentinel集群会对Redis的主从架构中的Redis实例进行监控,一旦发现了master节点宕机了,就会选举出一个Sentinel节点来执行故障转移,从原来的slave节点中选举出一个,将其晋升为master节点,而后让其余的节点去复制新选举进去的master节点。 你可能会感觉这样没有问题啊,甚至可能满足咱们生产环境的应用需要了,那咱们为什么还须要Redis Cluster呢? 为什么须要Redis Cluster确实,在数据上,有replication正本做保障;可用性上,master宕机会主动的执行failover。 那问题在哪儿呢?首先Redis Sentinel说白了也是基于主从复制,在主从复制中slave的数据是齐全来自于master。 假如master节点的内存只有4G,那slave节点所能存储的数据下限也只能是4G。而且在之前的追随杠精的视角一起来理解Redis的主从复制文章中也说过,主从复制架构中是读写拆散的,咱们能够通过减少slave节点来扩大主从的读并发能力,然而写能力和存储能力是无奈进行扩大的,就只能是master节点可能承载的下限。 所以,当你只须要存储4G的数据时候的,基于主从复制和基于Sentinel的高可用架构是齐全够用的。 然而如果当你面临的是海量的数据的时候呢?16G、64G、256G甚至1T呢?当初互联网的业务外面,如果你的体量足够大,我感觉是必定会面临缓存海量缓存数据的场景的。 这就是为什么咱们须要引入Redis Cluster。 Redis Cluster是什么晓得了为什么须要Redis Cluster之后,咱们就能够来对其一探到底了。 那什么是Redis Cluster呢?很简略,你就能够了解为n个主从架构组合在一起对外服务。Redis Cluster要求至多须要3个master能力组成一个集群,同时每个master至多须要有一个slave节点。 这样一来,如果一个主从可能存储32G的数据,如果这个集群蕴含了两个主从,则整个集群就可能存储64G的数据。 咱们晓得,主从架构中,能够通过减少slave节点的形式来扩大读申请的并发量,那Redis Cluster中是如何做的呢?尽管每个master下都挂载了一个slave节点,然而在Redis Cluster中的读、写申请其实都是在master上实现的。 slave节点只是充当了一个数据备份的角色,当master产生了宕机,就会将对应的slave节点提拔为master,来从新对外提供服务。 节点负载平衡晓得了什么是Redis Cluster,咱们就能够持续上面的探讨了。 不晓得你思考过一个问题没,这么多的master节点。我存储的时候,到底该抉择哪个节点呢?个别这种负载平衡算法,会抉择哈希算法。哈希算法是怎么做的呢? 首先就是对key计算出一个hash值,而后用哈希值对master数量进行取模。由此就能够将key负载平衡到每一个Redis节点下来。这就是简略的哈希算法的实现。 那Redis Cluster是采取的下面的哈希算法吗?答案是没有。 Redis Cluster其实采取的是相似于一致性哈希的算法来实现节点抉择的。那为什么不必哈希算法来进行实例抉择呢?以及为什么说是相似的呢?咱们持续探讨。 因为如果此时某一台master产生了宕机,那么此时会导致Redis中所有的缓存生效。为什么是所有的?假如之前有3个master,那么之前的算法应该是 hash % 3,然而如果其中一台master宕机了,则算法就会变成 hash % 2,会影响到之前存储的所有的key。而这对缓存前面爱护的DB来说,是致命的打击。 什么是一致性哈希晓得了通过传统哈希算法来实现对节点的负载平衡的弊病,咱们就须要进一步理解什么是一致性哈希。 咱们下面提过哈希算法是对master实例数量来取模,而一致性哈希则是对2^32取模,也就是值的范畴在[0, 2^32 -1]。一致性哈希将其范畴形象成了一个圆环,应用CRC16算法计算出来的哈希值会落到圆环上的某个中央。 而后咱们的Redis实例也散布在圆环上,咱们在圆环上依照顺时针的程序找到第一个Redis实例,这样就实现了对key的节点调配。咱们举个例子。 假如咱们有A、B、C三个Redis实例依照如图所示的地位散布在圆环上,此时计算出来的hash值,取模之后地位落在了地位D,那么咱们依照顺时针的程序,就可能找到咱们这个key应该调配的Redis实例B。同理如果咱们计算出来地位在E,那么对应抉择的Redis的实例就是A。 即便这个时候Redis实例B挂了,也不会影响到实例A和C的缓存。 例如此时节点B挂了,那之前计算出来在地位D的key,此时会依照顺时针的程序,找到节点C。相当于主动的把原来节点B的流量给转移到了节点C下来。而其余本来就在节点A和节点C的数据则齐全不受影响。 这就是一致性哈希,可能在咱们后续须要新增节点或者删除节点的时候,不影响其余节点的失常运行。 虚构节点机制然而一致性哈希也存在本身的小问题,例如当咱们的Redis节点散布如下时,就有问题了。 此时数据落在节点A上的概率显著是大于其余两个节点的,其次落在节点C上的概率最小。这样一来会导致整个集群的数据存储不均衡,AB节点压力较大,而C节点资源利用不充沛。为了解决这个问题,一致性哈希算法引入了虚构节点机制。 在圆环中,减少了对应节点的虚构节点,而后实现了虚构节点到实在节点的映射。假如当初计算得出了地位D,那么依照顺时针的程序,咱们找到的第一个节点就是C #1,最终数据理论还是会落在节点C上。 通过减少虚构节点的形式,使ABC三个节点在圆环上的地位更加平均,均匀了落在每一个节点上的概率。这样一来就解决了上文提到的数据存储存在不平均的问题了,这就是一致性哈希的虚构节点机制。 Redis Cluster采纳的什么算法下面提到过,Redis Cluster采纳的是类一致性哈希算法,之所以是类一致性哈希算法是因为它们实现的形式还稍微有差异。 例如一致性哈希是对2^32取模,而Redis Cluster则是对2^14(也就是16384)取模。Redis Cluster将本人分成了16384个Slot(槽位)。通过CRC16算法计算出来的哈希值会跟16384取模,取模之后失去的值就是对应的槽位,而后每个Redis节点都会负责解决一部分的槽位,就像下表这样。 ...

December 18, 2020 · 1 min · jiezi

关于redis:redis学习-sds字符串

redis学习 - sds字符串Redis 设计与实现:如果想要晓得redis底层,这本书能够给予不少的帮忙,十分举荐每一位学习redis的同学去翻一翻。 sds字符串倡议多看看源代码的实现,这篇文章根本是集体看了好几篇文章之后的笔记。 源代码文件别离是:sds.c,sds.h redis的string API应用首先看下API的简略利用,设置str1变量为helloworld,而后咱们应用debug object +变量名的形式看下,留神编码为embstr。 127.0.0.1:17100> set str1 helloworld-> Redirected to slot [5416] located at 127.0.0.1:17300OK127.0.0.1:17300> debug object str1Value at:0x7f2821c0e340 refcount:1 encoding:embstr serializedlength:11 lru:14294151 lru_seconds_idle:8如果咱们将str2设置为helloworldhelloworldhelloworldhelloworldhell,字符长度为44,再应用下debug object+变量名的形式看下,留神编码为embstr。 127.0.0.1:17300> set str2 helloworldhelloworldhelloworldhelloworldhell-> Redirected to slot [9547] located at 127.0.0.1:17100OK127.0.0.1:17100> get str2"helloworldhelloworldhelloworldhelloworldhell"127.0.0.1:17100> debug object str2Value at:0x7fd75e422c80 refcount:1 encoding:embstr serializedlength:21 lru:14294260 lru_seconds_idle:6然而当咱们把设置为helloworldhelloworldhelloworldhelloworldhello,字符长度为45,再应用debug object+变量名的形式看下,留神编码扭转了,变为raw。 127.0.0.1:17100> set str2 helloworldhelloworldhelloworldhelloworldhelloOK127.0.0.1:17100> debug object str2Value at:0x7fd75e430c60 refcount:1 encoding:raw serializedlength:21 lru:14294358 lru_seconds_idle:9最初咱们将其设置为整数100,再应用debug object+变量名的形式看下,编码的格局变为了int。 ...

December 16, 2020 · 5 min · jiezi

关于redis:Redis6安装下-集群与故障转移

Redis Cluster 搭建筹备工作搭建集群之前,务必有一点须要留神就是选举,因为在现在很多的分布式中间件里,集群都会有选举这个概念,肯定要达到半数以上的节点,才可能发动偏心的投票,否则就会脑裂,比方redis,zk,es等,所以至多保障3个master节点,master会发动选举投票的。这一点要须知。配置6个节点的虚拟机(事后做好) 192.168.1.221192.168.1.222192.168.1.223192.168.1.224192.168.1.225192.168.1.226192.168.1.227(新增Master)192.168.1.228(新增Slave)每个节点搭建单机redis,清理aof和rdb文件(事后做好)如果为单实例的Redis设置了明码password,那么每个节点都必须要设置masterauth,也就是对应明码,这样是为了master挂掉当前,对应的slave能够降级为master。须要留神,选举的过程会短暂的对外不可用。Redis Cluster 搭建实操演练附:敞开redis ./redis-cli -p <批改的端口号> -a <批改的明码> shutdown 开启redis: ./redis-server redis.conf 每个单实例中的 redis.conf 配置: # 配置redis日志,便于查看logfile /usr/local/redis/redis-221.log # 开启集群模式cluster-enabled yes# 每一个节点须要有一个配置文件,须要6份。每个节点处于集群的角色都须要告知其余所有节点,彼此晓得,这个文件用于存储集群模式下的集群状态等信息,这个文件是由redis本人保护,咱们不必管。如果你要从新创立集群,那么把这个文件删了就行cluster-config-file nodes-221.conf# 超时工夫,超时则认为master宕机,随后主备切换cluster-node-timeout 5000# 开启AOFappendonly yes 创立集群,在任意节点运行如下命令一次: ###### 留神1:如果你应用的是redis3.x版本,须要应用redis-trib.rb来构建集群,最新版应用C语言来构建了,这个要留神# 留神2:以下为新版的redis构建形式###### 创立集群,主节点和从节点比例为1,1-3为主,4-6为从,这也是最经典用的最多的集群模式。cluster-replicas是几个slave,-a是执行机密。./redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1 -a 123456 从上图中能够看到,slots槽,用于装数据,主节点有,从节点没有。 在任意节点查看集群信息: ./redis-cli --cluster check 192.168.1.221:6379 -a 123456 查看主从状态信息: ./redis-cli -a 123456info replication 搭建集群时的日志M221与S225 M222与S226 M223与S224 从节点日志,次要进行复制: ...

December 16, 2020 · 1 min · jiezi

关于redis:Redis6安装上-单机单实例

首先下载新版的redis6并且上传到centos7:装置redis须要gcc的环境,和以往老版本不同,这里的gcc须要高一点的版本。 yum install gcc-c++ 随后降级gcc版本 yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash 永恒配置gcc9的环境 echo -e "nsource /opt/rh/devtoolset-9/enable" >>/etc/profile 再次查看,gcc的版本曾经更新gcc装置结束当前,接下来能够依照redis了,解压redis6安装包 tar -zxvf redis-6.0.9.tar.gz 进入到这个解压后的文件夹,编译并且装置redis makemake install PREFIX=/usr/local/redis 装置好之后须要配置一下,先复制配置文件到装置目录:而后vim批改这个文件 后盾启动 任何ip都能连 批改明码 redis在后盾镜像运行,个别定义一个日志,便于查看 运行redis ./redis-server redis.conf 查看日志,示意运行胜利 vim /usr/local/redis/redis.log 开启redis客户端工具,并且测试应用RDS工具连贯并查看:至此,Redis6装置胜利,其实和5.x也是一样的,只是gcc版本须要降级,所有有些小伙伴装置的时候会编译出错。

December 16, 2020 · 1 min · jiezi

关于redis:redis内存优化策略

1、背景redis作为缓存零碎,内存可存储的数据必然比物理硬盘要少得多,所以咱们不能无止境的往内存中存储大量的数据,除此之外还须要定期对数据做清理工作。以保障内存零碎的失常运行。 2、算法介绍2.1 LRU算法LRU是Least Recently Used的缩写,顾名思义就是最近起码应用,是比拟罕用的页面置换算法,抉择最久没有应用的页面给予淘汰。该算法赋予每个页面一个拜访字段,用来记录页面最新一次被拜访的工夫t,当必须淘汰一个页面时,抉择现有页面工夫t间隔最久的,即最近起码应用的页面给予淘汰。是依据工夫维度来判断的。 2.2 LFU算法LFU(Least Frequently Used (LFU) page-replacement algorithm),即最不常应用页置换算法,要求在页置换时援用计数最小的页,因为常常应用的页应该有一个较大的援用次数。然而有些页在开始时应用的次数较多,但当前将不再应用了,然而因为领有较大的援用次数,所以每次淘汰的页面都不会有它,因而每次淘汰后都将计数值右移一位,如此一来通过几轮淘汰后,计数大且近期不必的页也可能被淘汰。是依据应用次数作为维度来判断的。 2.3 随机算法随机去筛选淘汰页面。 2.4 TTL将超时工夫最短的数据,提前删除。 3、redis内存优化抉择能够批改redis.conf文件中的maxmemory-policy的值来抉择采纳哪种算法进行优化①volatile-lru:在设定超时工夫的数据中采纳LRU算法②allkeys-lru:所有的数据采纳LRU算法删除③volatile-lfu:设定了超时工夫的数据采纳LFU算法删除④allkeys-lfu:所有数据采纳LFU算法删除⑤volatile-random:设定了超时工夫的数据采纳随机算法⑥allkeys-random:所有数据的随机算法⑦volatile-ttl:设定了超时工夫之后采纳TTL算法⑧noeviction:不做任何操作,只是返回报错信息

December 15, 2020 · 1 min · jiezi

关于redis:Redis缓存

1.redis1.1什么事redisRedis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它能够用作数据库、缓存和消息中间件。 它反对多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 汇合(sets), 有序汇合(sorted sets) 与范畴查问, bitmaps, hyperloglogs 和 天文空间(geospatial) 索引半径查问。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘长久化(persistence), 并通过 Redis哨兵(Sentinel)和主动 分区(Cluster)提供高可用性(high availability)。 速度: 读: 11.2万/秒 写:8.6万/秒 50万/秒 1.2redis的做用引入缓存机制能够无效的缩小用户拜访物理设施的次数,从而进步相应速度; 1.2如何设计缓存?1.缓存数据如何存储? 应该采纳什么样的数据结构呢? K-V key的唯一性2.缓存数据的容量大小 应该动静保护缓存数据,将不须要的数据提前删除. LRU算法/LFU算法/随机算法/TTL算法3.缓存数据保留到内存中,然而内存的特点断电即擦除. 定期将内存数据长久化(写入磁盘中)4.单台缓存服务器性能有余,所以个别须要搭建集群(实现高可用).5.应用C语言开发. 2 Redis属性阐明2.1 Redis长久化策略2.1.1 为什么要长久化Redis中的记录都保留在内存中,如果内存断电或者服务器宕机,则内存数据间接失落.业务中不容许产生. 所以须要将数据定期进行保护. 2.1.2 RDB模式阐明: RDB模式是Redis的默认的长久化策略.无需手动的开启.特点:1.Redis会定期的执行RDB长久化操作. 毛病:可能导致内存数据失落.2.RDB记录的是内存数据的快照,并且后续的快照会笼罩之前的快照.每次只保留最新数据.效率更高. 命令:1).save 命令 要求立刻执行长久化操作 save会造成线程的阻塞.2).bgsave 命令 后盾执行长久化操作 后盾运行不会造成阻塞. 异步操作, 不能保障立刻执行 2.1.3 AOF模式阐明: AOF模式默认条件下是敞开的,须要手动的开启,如果开启了AOF模式则RDB模式将生效.然而如果手动执行save命令,则也会生成RDB文件. 1).开启AOF模式特点:1.AOF模式记录程序的执行的过程.所以能够保证数据不失落.2.因为AOF记录程序运行的过程,所以整个长久化文件绝对大,所以须要定期维护. 效率低 .1.4 RDB与AOF模式长久化比照1).RDB模式save 900 1 如果在900秒内,执行了一次更新操作则长久化一次save 300 10save 60 10000 操作越快 ,长久化的周期越短. ...

December 13, 2020 · 2 min · jiezi

关于redis:Redis-的-8-大数据类型写得非常好

NoSQL 开发中或多或少都会用到,也是面试必问知识点。最近这几天的面试每一场都问到了。然而感觉答复的并不好,还有很多须要梳理的知识点。 官网可查看命令:http://www.redis.cn/commands.... Redis-key127.0.0.1:6379> keys *(empty list or set)127.0.0.1:6379> set name xxxOK127.0.0.1:6379> keys *1) "name"127.0.0.1:6379> set age 1OK127.0.0.1:6379> keys *1) "age"2) "name"127.0.0.1:6379> exists name  # 判断key 是否存在(integer) 1127.0.0.1:6379> exists name1(integer) 0127.0.0.1:6379> move name 1(integer) 1127.0.0.1:6379> keys *1) "age"127.0.0.1:6379> set name yyyOK127.0.0.1:6379> expire name 10  # 设置key的过期工夫,单位是秒(integer) 1127.0.0.1:6379> ttl name  # 查看以后key的残余过期工夫(integer) 7127.0.0.1:6379> ttl name(integer) -2127.0.0.1:6379> type age  # 查看以后key的类型string127.0.0.1:6379>Redis 有以下 5 种根本的数据类型 1、String(字符串)127.0.0.1:6379> set key1 v1   #设置值OK127.0.0.1:6379> get key1"v1"127.0.0.1:6379> append key1 "hello"  # 追加值,如果不存在,相当于 set key(integer) 7127.0.0.1:6379> get key1"v1hello"127.0.0.1:6379> strlen key1  # 获取字符串长度(integer) 7127.0.0.1:6379>自增、自减 127.0.0.1:6379> set views 0OK127.0.0.1:6379> get views"0"127.0.0.1:6379> incr views  # 自增 1(integer) 1127.0.0.1:6379> get views"1"127.0.0.1:6379> decr views       # 自减 1(integer) 0127.0.0.1:6379> decr views(integer) -1127.0.0.1:6379> get views"-1"127.0.0.1:6379> incrby views 10  # 设置步长、自增 10 (integer) 9127.0.0.1:6379> decrby views 5      # 设置步长、自减 5(integer) 4字符串范畴 127.0.0.1:6379> set key1 "hello,world!"OK127.0.0.1:6379> get key1"hello,world!"127.0.0.1:6379> getrange key1 0 3  # 截取字符串[0, 3]"hell"127.0.0.1:6379> getrange key1 0 -1  # 获取全副的字符串,和 get key一样"hello,world!"127.0.0.1:6379>替换: 127.0.0.1:6379> set key2 abcdefgOK127.0.0.1:6379> get key2"abcdefg"127.0.0.1:6379> setrange key2 1 xx(integer) 7127.0.0.1:6379> get key2"axxdefg"127.0.0.1:6379>setex(set with expire):设置过期工夫 和setnx(set if not exist):不存在再设置(在分布式锁中会常常应用) 127.0.0.1:6379> setex key3 30 "hello"  # 设置 30 秒后过期OK127.0.0.1:6379> ttl key3     # 残余过期工夫(integer) 25127.0.0.1:6379> setnx mykey "redis"   # mykey 不存在时设置胜利(integer) 1127.0.0.1:6379> keys *1) "key2"2) "key1"3) "views"4) "mykey"127.0.0.1:6379> setnx mykey "mongoDB"  # mykey 存在时设置失败(integer) 0127.0.0.1:6379> get mykey     # mykey 值不变"redis"127.0.0.1:6379>mset 和 mget 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  # 同时设置多个值OK127.0.0.1:6379> keys *1) "k1"2) "k3"3) "k2"127.0.0.1:6379> mget k1 k2 k3   # 同时获取多个值1) "v1"2) "v2"3) "v3"127.0.0.1:6379> msetnx k1 v1 k4 v4       # msetnx 是一个原子性的操作,要么一起胜利,要么都失败(integer) 0127.0.0.1:6379> get k4(nil)127.0.0.1:6379>对象 set user:1 {name:zhangsan, age:3}     # 设置一个 user:1 对象 值为 json  字符来保留一个对象127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2OK127.0.0.1:6379> mget user:1:name user:1:age1) "zhangsan"2) "2"127.0.0.1:6379>getset:先 get 再 set 127.0.0.1:6379> getset db redis  # 如果不存在值,则返回 nil(nil)127.0.0.1:6379> get db"redis"127.0.0.1:6379> getset db mongodb  # 如果存在值,获取原来的值,并设置新的值"redis"127.0.0.1:6379> get db"mongodb"127.0.0.1:6379>String 的应用场景:value 除了是字符串以外还能够是数字 计数器统计多单位的数量粉丝数对象缓存存储2、List(列表)根本的数据类型,列表。 在 Redis 中能够把 list 用作栈、队列、阻塞队列。 list 命令少数以 l结尾。 127.0.0.1:6379> lpush list one   # 将一个值或者多个值,插入到列表的头部(左)(integer) 1127.0.0.1:6379> lpush list two(integer) 2127.0.0.1:6379> lpush list three (integer) 3127.0.0.1:6379> lrange list 0 -1   # 查看全副元素1) "three"2) "two"3) "one"127.0.0.1:6379> lrange list 0 1    # 通过区间获取值1) "three"2) "two"127.0.0.1:6379> rpush list right   # 将一个值或者多个值,插入到列表的尾部(右)(integer) 4127.0.0.1:6379> lrange list 0 -11) "three"2) "two"3) "one"4) "right"127.0.0.1:6379>弹出 pop 127.0.0.1:6379> lrange list 0 -11) "!"2) "world"3) "world"4) "hello"127.0.0.1:6379> lpop list  # 移除list的第一个元素"!"127.0.0.1:6379> lrange list 0 -11) "world"2) "world"3) "hello"127.0.0.1:6379> rpop list   # 移除list的第一个元素"hello"127.0.0.1:6379> lrange list 0 -11) "world"2) "world"127.0.0.1:6379>索引 Lindex 127.0.0.1:6379> lrange list 0 -11) "hjk"2) "world"3) "world"127.0.0.1:6379> lindex list 1  # 通过下标获取list中的某一个值"world"127.0.0.1:6379> lindex list 0"hjk"127.0.0.1:6379>Llen 长度: 127.0.0.1:6379> llen list(integer) 3127.0.0.1:6379>移除指定的值: 127.0.0.1:6379> lrange list 0 -11) "hjk"2) "world"3) "world"127.0.0.1:6379> lrem list 1 world  # 移除list汇合中指定个数的value,准确匹配(integer) 1127.0.0.1:6379> lrange list 0 -11) "hjk"2) "world"127.0.0.1:6379> lpush list hjk(integer) 3127.0.0.1:6379> lrange list 0 -11) "hjk"2) "hjk"3) "world"127.0.0.1:6379> lrem list 2 hjk(integer) 2127.0.0.1:6379> lrange list 0 -11) "world"127.0.0.1:6379>trim 截断 127.0.0.1:6379> lrange mylist 0 -11) "hello1"2) "hello2"3) "hello3"4) "hello4"127.0.0.1:6379> ltrim mylist 1 2 # 通过下标截取指定长度,这个list曾经被毁坏了,截断之后只剩下截断后的元素OK127.0.0.1:6379> lrange mylist 0 -11) "hello2"2) "hello3"127.0.0.1:6379>rpoplpush :移除列表的最初一个元素,将他挪动到新的列表中。 127.0.0.1:6379> lrange mylist 0 -11) "hello1"2) "hello2"3) "hello3"127.0.0.1:6379> rpoplpush mylist myotherlist  # 移除列表的最初一个元素,将他挪动到新的列表中。"hello3"127.0.0.1:6379> lrange mylist 0 -1  # 查看原来的列表1) "hello1"2) "hello2"127.0.0.1:6379> lrange myotherlist 0 -1  # 查看指标列表中,的确存在该值1) "hello3"127.0.0.1:6379>lset:将列表中指定下标的值替换为另一个值,更新操作 127.0.0.1:6379> exists list  # 判断这个列表是否存在(integer) 0127.0.0.1:6379> lset list 0 item  # 如果不存在的话,更新会报错(error) ERR no such key127.0.0.1:6379> lpush list value1(integer) 1127.0.0.1:6379> lrange list 0 0 1) "value1"127.0.0.1:6379> lset list 0 item  # 如果存在,更新以后下标的值OK127.0.0.1:6379> lset list 1 other  # 如果不存在的话,更新会报错(error) ERR index out of range127.0.0.1:6379>linsert:将某个具体的value插入到列表中某个元素的后面或者前面 127.0.0.1:6379> lrange mylist 0 -11) "hello1"2) "hello2"127.0.0.1:6379> linsert mylist before "hello2" hello(integer) 3127.0.0.1:6379> lrange mylist 0 -11) "hello1"2) "hello"3) "hello2"127.0.0.1:6379> linsert mylist after "hello2" hello(integer) 4127.0.0.1:6379> lrange mylist 0 -11) "hello1"2) "hello"3) "hello2"4) "hello"127.0.0.1:6379>小结: list 实际上是一个链表,前后都能够插入如果key不存在,创立新的链表如果移除了所有的值,空链表,也代表不存在在两边插入或者改变值,效率最高。3、Set (汇合)127.0.0.1:6379> sadd myset "hello"  # set 汇合中增加元素(integer) 1127.0.0.1:6379> sadd myset "world"  (integer) 1127.0.0.1:6379> smembers myset      # 查看指定Set的所有值1) "world"2) "hello"127.0.0.1:6379> sismember myset hello  # 判断某一个值是不是在set中(integer) 1127.0.0.1:6379> sismember myset hello1(integer) 0127.0.0.1:6379>127.0.0.1:6379> scard myset  # 获取汇合中的个数(integer) 2127.0.0.1:6379> sadd myset "hello2"  (integer) 1127.0.0.1:6379> smembers myset   1) "world"2) "hello2"3) "hello"127.0.0.1:6379> srem myset hello   # 移除元素(integer) 1127.0.0.1:6379> smembers myset1) "world"2) "hello2"127.0.0.1:6379>127.0.0.1:6379> smembers myset1) "kkk"2) "world"3) "hjk"4) "hello2"127.0.0.1:6379> srandmember myset   # 随机抽取一个元素"hjk"127.0.0.1:6379> srandmember myset"hello2"127.0.0.1:6379> srandmember myset 2   # 随机抽取指定个数的元素1) "world"2) "hello2"127.0.0.1:6379> srandmember myset 21) "hello2"2) "hjk"127.0.0.1:6379>127.0.0.1:6379> smembers myset1) "kkk"2) "world"3) "hjk"4) "hello2"127.0.0.1:6379> spop myset  # 随机删除元素"hjk"127.0.0.1:6379> smembers myset1) "kkk"2) "world"3) "hello2"127.0.0.1:6379> spop myset"hello2"127.0.0.1:6379> smembers myset1) "kkk"2) "world"127.0.0.1:6379>127.0.0.1:6379> smembers myset1) "kkk"2) "world"127.0.0.1:6379> sadd myset2 set2(integer) 1127.0.0.1:6379> smove myset myset2 "kkk"   # 将一个特定的值,挪动到另一个set汇合中(integer) 1127.0.0.1:6379> smembers myset1) "world"127.0.0.1:6379> smembers myset21) "kkk"2) "set2"127.0.0.1:6379>127.0.0.1:6379> smembers key11) "b"2) "a"3) "c"127.0.0.1:6379> smembers key21) "e"2) "d"3) "c"127.0.0.1:6379> sdiff key1 key2   # 差集1) "b"2) "a"127.0.0.1:6379> sinter key1 key2    # 交加1) "c"127.0.0.1:6379> sunion key1 key2  # 并集1) "e"2) "a"3) "c"4) "d"5) "b"4、Hash(哈希)也是 key - value 模式的,然而value 是一个map。 127.0.0.1:6379> hset myhash field xxx  # set 一个 key-value(integer) 1127.0.0.1:6379> hget myhash field   # 获取一个字段值"xxx"127.0.0.1:6379> hmset myhash field1 hello field2 world  # set 多个 key-valueOK127.0.0.1:6379> hmget myhash field field1 field2   # 获取多个字段值1) "xxx"2) "hello"3) "world"127.0.0.1:6379> hgetall myhash    # 获取全副的数据1) "field"2) "xxx"3) "field1"4) "hello"5) "field2"6) "world"127.0.0.1:6379> hdel myhash field1  # 删除指定的key,对应的value也就没有了(integer) 1127.0.0.1:6379> hgetall myhash1) "field"2) "xxx"3) "field2"4) "world"127.0.0.1:6379>127.0.0.1:6379> hlen myhash  # 获取长度(integer) 2127.0.0.1:6379> hexists myhash field1   # 判断指定key是否存在(integer) 0127.0.0.1:6379> hexists myhash field2(integer) 1127.0.0.1:6379> hkeys myhash  # 获取所有的key1) "field"2) "field2"127.0.0.1:6379> hvals myhash  # 获取所有的value1) "xxx"2) "world"127.0.0.1:6379>127.0.0.1:6379> hset myhash field3 5  (integer) 1127.0.0.1:6379> hincrby myhash field3 1  # 指定增量(integer) 6127.0.0.1:6379> hincrby myhash field3 -1(integer) 5127.0.0.1:6379> hsetnx myhash field4 hello  # 如果不存在则能够设置(integer) 1127.0.0.1:6379> hsetnx myhash field4 world  # 如果存在则不能设置(integer) 0127.0.0.1:6379>Hash 适宜存储常常变动的对象信息,String 更适宜于存储字符串。 5、zset (有序汇合)127.0.0.1:6379> zadd myset 1 one  # 增加一个值(integer) 1127.0.0.1:6379> zadd myset 2 two 3 three # 增加多个值(integer) 2127.0.0.1:6379> zrange myset 0 -11) "one"2) "two"3) "three"127.0.0.1:6379>实现排序: ...

December 13, 2020 · 1 min · jiezi

关于redis:SpringBoot整合Redis集群

Redis集群为什么须要搭建集群:通常,为了进步网站响应速度,总是把热点数据保留在内存中而不是间接从后端数据库中读取。Redis是一个很好的Cache工具。大型网站利用,热点数据量往往微小,几十G上百G是很失常的事儿。因为内存大小的限度,应用一台 Redis 实例显然无奈满足需要,这时就须要应用多台 Redis作为缓存数据库。然而如何保证数据存储的一致性呢,这时就须要搭建redis集群.采纳正当的机制,保障用户的失常的拜访需要.采纳redis集群,能够保证数据扩散存储,同时保证数据存储的一致性.并且在外部实现高可用的机制.实现了服务故障的主动迁徙. 集群搭建打算测试主从划分:3台主机 3台从机共6台 端口划分7000-7005 集群搭建1.创立集群文件夹: Mkdir cluster2.在文件夹中创立多个文件:mkdir 7000 7001 7002 7003 7004 7005 复制配置文件将redis根目录中的redis.conf文件复制到cluster/7000/ 并以原名保留cp redis.conf cluster/7000/ 编辑配置文件1.正文本地绑定IP地址 2.敞开保护模式 3.批改端口号 4.启动后盾启动 5.批改pid文件 6.批改长久化文件门路 7.设定内存优化策略 8.敞开AOF模式 9.开启集群配置 10.开启集群配置文件 11.批改集群超时工夫 复制批改后的配置文件将7000文件夹下的redis.conf文件别离复制到7001-7005中 批量批改别离将7001-7005文件中的7000改为对应的端口号的名称,批改时留神方向键的应用 通过脚本编辑启动/敞开指令1.创立启动脚本 vim start.sh 2.编辑敞开的脚本 vim shutdown.sh 3.启动redis节点: sh start.sh4.查看redis节点启动是否失常: ps -ef | grep redis 创立redis集群指令:redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7000 192.168.126.129:7001 192.168.126.129:7002 192.168.126.129:7003 192.168.126.129:7004 192.168.126.129:7005 Redis集群高可用测试1.敞开redis主机.查看是否主动实现故障迁徙.2.再次启动敞开的主机.查看是否可能实现主动的挂载.个别状况下 可能实现主从挂载个别情况:宕机后的节点重启,可能挂载到其余主节点中(7001-7002)正确的. Redis集群原理Reids集群高可用推选原理原理解析:Redis的所有节点都会保留以后redis集群中的全副主从状态信息.并且每个节点都可能互相通信.当一个节点产生宕机景象.则集群中的其余节点通过PING-PONG检测机制查看Redis节点是否宕机.当有半数以上的节点认为宕机.则认为主节点宕机.同时由Redis残余的主节点进入选举机制.投票选举链接宕机的主节点的从机.实现故障迁徙. Redis进群宕机条件特点:集群中如果主机宕机,那么从机能够持续提供服务,当主机中没有从机时,则向其它主机借用多余的从机.持续提供服务.如果主机宕机时没有从机可用,则集群解体. Redis hash槽贮存数据原理RedisCluster采纳此分区,所有的键依据哈希函数(CRC16[key]%16384)映射到0-16383槽内,共16384个槽位,每个节点保护局部槽及槽所映射的键值数据.依据主节点的个数,平衡划分区间.算法:哈希函数: Hash()=CRC16[key]%16384 当向redis集群中插入数据时,首先将key进行计算.之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到治理该槽的节点中. ...

December 11, 2020 · 1 min · jiezi

关于redis:Redis分片机制

redis性能优化秒速:单台redis内存容量是无限的.然而如果有海量的数据要求实现缓存存储,则应该应用多个Redis节点.Redis分片机制定义: Redis分片机制配置配置布局配置形容:筹备3台redis服务器,端口号别离为6379/6380/6381 1.筹备3个配置文件 2.别离批改端口号: 3.启动redis服务器 4.查看redis启动状态 5.案例测试 6.依据redis节点个数.拼接字符串 7.编辑RedisConfig配置类@Configuration //标识我是一个配置类 个别与@Bean注解联用@PropertySource("classpath:/properties/redis.properties")public class RedisConfig { @Value("${redis.nodes}")private String nodes; //node,node,node@Beanpublic ShardedJedis shardedJedis(){ List<JedisShardInfo> shards = new ArrayList<>(); String[] nodeArray = nodes.split(","); for( String node :nodeArray){ //node=host:port String host = node.split(":")[0]; int port = Integer.parseInt(node.split(":")[1]); JedisShardInfo info = new JedisShardInfo(host,port); shards.add(info); } return new ShardedJedis(shards);}}8.批改CacheAOP中的注入

December 9, 2020 · 1 min · jiezi

关于redis:Redis-持久化是如何做的一文聊聊-RDB和AOF对比分析

这篇文章咱们来介绍Redis高可用相干的机制。Redis要想实现高可用,次要有以下方面来保障: 数据长久化主从复制主动故障复原集群化这篇文章咱们先介绍Redis的高可用保障的根底:数据长久化。因为Redis的主从复制和主动故障复原,都须要依赖Redis长久化相干的货色。同时,Redis的数据长久化也能够用来做数据备份,用来保障数据的安全性。 Redis是一个内存数据库,它的数据都保留在内存中,如果实例宕机,那么数据则全副失落。如何保证数据的完整性和安全性也是进步服务高可用的重要机制之一。 Redis提供了欠缺的长久化机制,能够把内存中的数据长久化到磁盘上,不便咱们进行备份数据和疾速复原数据。 这篇文章咱们就来剖析Redis的数据长久化是如何实现的?咱们常常听的RDB和AOF有什么区别?以及它们不同的应用场景。 长久化形式Redis提供的数据长久化形式次要有2种: RDB:产生一个数据快照文件AOF:实时追加命令的日志文件它们别离对应了不同的应用场景,上面咱们就来顺次剖析。 RDB介绍 RDB全称 Redis Database Backup file(Redis数据备份文件),也被叫做 Redis 数据快照。 咱们能够通过执行save或bgsave命令让 Redis 在本地生成RDB快照文件,这个RDB文件蕴含了整个实例靠近残缺的数据内容。它的长处如下: RDB文件数据是被压缩写入的,因而RDB文件的体积要比整个实例内存要小当实例宕机复原时,加载RDB文件的速度很快,可能在很短时间内迅速复原文件中的数据它的毛病也很显著: 因为是某一时刻的数据快照,因而它的数据并不全生成 RDB 文件的代价是比拟大的,它会耗费大量的 CPU 和内存资源因而RDB比拟实用于以下场景: 主从全量同步数据数据库备份对于失落数据不敏感的业务场景,实例宕机后疾速复原数据Redis主从全量同步数据就是应用RDB文件进行的,咱们会在前面的文章具体讲到。 由此能够看出,RDB非常适合做数据备份,咱们能够定时让Redis生成RDB文件,而后备份这个快照文件即可。 定时生成RDBRedis也提供了定时触发生成RDB文件的配置项: # 最近15分钟内 至多产生1次写入save 900 1# 最近5分钟内 至多产生10次写入save 300 10# 最近1分钟内 至多产生10000次写入save 60 10000如果达到以上任意条件,则Redis会主动生成新的RDB文件,升高RDB数据内容与实例数据的差别。 Copy On Write在Redis上执行save和bgsave命令都能够生成RDB文件,但前者是在前台执行的,也就是说在生成RDB文件时,会阻塞整个实例,在RDB未生成之前,任何申请都是无奈解决的,对于内存很大的实例,生成RDB文件十分耗时,显然这是咱们不能承受的。 所以通常咱们会抉择执行bgsave让Redis在后盾生成RDB文件,这样Redis仍旧能够解决客户端申请,不会阻塞整个实例。 但不是说后盾生成RDB就是没有代价的,Redis为了实现后盾把内存数据的快照写入文件,采纳了操作系统提供的Copy On Write技术,也就是咱们熟知的fork零碎调用。 fork 零碎调用会产生一个子过程,它与父过程共享雷同的内存地址空间,这样子过程在这一时刻就能领有与父过程的雷同的内存数据。 尽管子过程与父过程共享同一块内存地址空间,但在fork子过程时,操作系统须要拷贝父过程的内存页表给子过程,如果整个Redis实例内存占用很大,那么它的内存页表也会很大,在拷贝时就会比拟耗时,同时这个过程会耗费大量的CPU资源。在实现拷贝之前父过程也处于阻塞状态,无奈解决客户端申请。 fork执行完之后,子过程就能够扫描本身所有的内存数据,而后把全副数据写入到RDB文件中。 之后父过程仍旧解决客户端的申请,当在解决写命令时,父过程会重新分配新的内存地址空间,从操作系统申请新的内存应用,不再与子过程共享,这个过程就是Copy On Write(写实复制)名字的由来。这样父子过程的内存就会逐步拆散,父过程申请新的内存空间并更改内存数据,子过程的内存数据不受影响。 由此能够看出,在生成RDB文件时,不仅耗费CPU资源,还有须要占用最多一倍的内存空间。 咱们在 Redis 执行info命令,能够看到fork子过程的耗时,能够通过这个耗时来评估fork工夫是否合乎预期。同时咱们应该保障Redis机器领有足够的CPU和内存资源,并正当设置生成RDB的机会。 AOF介绍 AOF全称为Append Only File(追加日志文件)。它与RDB不同的是,AOF中记录的是每一个命令的详细信息,包含残缺的命令类型、参数等。只有产生写命令,就会实时写入到AOF文件中。 咱们能够通过配置文件开启AOF: # 开启AOFappendonly yes# AOF文件名appendfilename "appendonly.aof"# 文件刷盘形式appendfsync everysec刷盘形式开启AOF后,Redis会把每个写操作的命令记录到文件并长久化到磁盘中,为了保障数据文件的安全性,Redis还提供了文件刷盘的机会: appendfsync always:每次写入都刷盘,对性能影响最大,占用磁盘IO比拟高,数据安全性最高appendfsync everysec:1秒刷一次盘,对性能影响绝对较小,节点宕机时最多失落1秒的数据appendfsync no:依照操作系统的机制刷盘,对性能影响最小,数据安全性低,节点宕机失落数据取决于操作系统刷盘机制以上能够看出AOF绝对于RDB的长处是,AOF数据文件更新比拟及时,比RDB保留更残缺的数据,这样在数据恢复时可能复原尽量残缺的数据,升高失落数据的危险。 如果同时存在RDB文件和AOF文件,Redis会优先应用AOF文件进行数据恢复。 但它的毛病也很易见: 随着工夫增长,AOF文件会越来越大AOF文件刷盘会减少磁盘IO的累赘,可能影响Redis的性能(开启每秒刷盘时)AOF重写针对第一种状况,Redis提供了AOF瘦身的性能,能够设置在AOF文件很大时,主动触发AOF重写,Redis会扫描整个实例的数据,从新生成一个AOF文件达成瘦身的成果。但这个重写过程也须要耗费大量的CPU资源。 # AOF文件间隔上次文件增长超过多少百分比则触发重写auto-aof-rewrite-percentage 100# AOF文件体积最小多大以上才触发重写auto-aof-rewrite-min-size 64mb因为AOF能够最大可能升高失落数据的危险,所以它个别实用于对失落数据很敏感的业务场景,例如波及金钱交易的业务。 性能影响如果AOF的刷盘机会设置为每次写入都刷盘,那么会大大降低Redis的写入性能,因为每次写命令都须要写入文件并刷到磁盘中才会返回,当写入量很大时,会减少磁盘IO的累赘。性能与数据安全不能兼得,尽管Redis提供了实时刷盘的机制,然而在真正场景中应用的不多。 通常咱们会抉择每秒刷盘这种形式,既能保障良好的写入性能,在实例宕机时最多失落1秒的数据,做到性能和平安的均衡。 总结咱们对RDB和AOF的总结如下表。咱们须要针对不同的业务场景抉择适合的长久化形式,也能够依据RDB和AOF的长处配合应用,保障Redis数据的安全性,又能够兼顾它的性能。 作者:Kaito链接:http://kaito-kidd.com/2020/06... ...

December 8, 2020 · 1 min · jiezi

关于redis:Redis缓存服务器

网址:http://www.redis.cn/提前准备:虚拟机redis介绍redis是一个开源的(BSD许可),内存中的数据结构存储系统,它能够用作数据库、缓存、消息中间件。它反对多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(lists)、汇合(sets)、有序汇合(sorted sets)与范畴查问,bitmaps,hyperloglogs和天文空间(geospatial)索引半径查问。redis内置了复制(replication)、LUA脚本(Lua scripting),LRU驱动事件(LUR eviction),事务(transactions)和不同级别的磁盘长久化(persistence),并通过redis哨兵(Sentinel)和主动分区(Cluster)提供高可用性(high availability)。nginx: 3-5万/秒redis:读:11.2万/秒 写:8.6万/秒 均匀10万/秒 吞吐量:50万/秒 redis装置1、下载redis-5.0.4.tar.gz,并上传至 2、解压redis文件tar -xvf redis-5.0.4.tar.gz3、挪动文件/批改文件 4、装置redis(该命令执行工夫较长)命令1:make命令2:make install 批改redis.conf配置文件1、批改IP绑定 2、敞开保护模式 3、开启后盾启动 redis命令1、启动redis redis-server redis.conf 2、查看redis服务项 ps -ef|grep redis 3、进入redis客户端 redis-cli -p 6379redis-cli 4、敞开redis //退出客户端ctrl+c形式(1) redis-cli -p 6379 shutdown//默认端口6379时,就能够省略redis-cli 形式(2) ps -ef|grep rediskill -9 pid 罕用的redis命令string类型set --set username admin --增加key-valueget --get username --依据key获取数据strlen --stalen key --依据key获取值的长度exists --exists name --判断key是否存在 del --del key --删除redis中的keykeys --keys * --查问redis中全副的key --keys n?me --应用占位符获取数据 --keys nam* --获取nam结尾的数据 mset --mset key1 value1 key2 value2 key3 value3 --赋值多个key-valuemget --mget key1 key2 --获取多个key的值append --append key value --对某个key的值进行追加type --type key --查看某个key的类型select --select 0-15 redis中共有16个数据库 --切换redis数据库flushdb --flushdb --清空单个熟客flushall --flushall --清空全副数据库incr --incr key --主动加1decr --decr key --主动减1incrby --incrby 10 --指定数值增加decrby --decrby 10 --指定数值缩小expire --expire key 20 --key20秒后生效pexpire --pexpire key 2000 --key2000毫秒后生效ttl --ttl key -2数据不存在 -1该数据永不超时 --查看key的残余存活工夫

December 7, 2020 · 1 min · jiezi

关于redis:Redis缓存及相关指令

Redis缓存系统优化策略:作用:引入缓存机制能够无效的升高用户拜访物理设施的频次,从而进步响应速度. 如何设计缓存1)缓存数据如何存储?应该采纳什么样的数据结构呢?K-V key的唯一性2)缓存数据的容量大小应该动静保护缓存数据.将不须要的数据提前删除.LRU算法/LFU算法/随机算法/TTL算法.3)缓存数据保留到内存中,然而内存的特点断电即擦除.定期将内存数据长久化(写入磁盘中).4)单台缓存服务器性能有余,所以个别须要搭建集群(实现高可用).5)应用C语言开发(nginx也是C开发). Redis缓存服务什么是Redis?Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它能够用作数据库、缓存和消息中间件。 它反对多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 汇合(sets), 有序汇合(sorted sets) 与范畴查问, bitmaps, hyperloglogs 和 天文空间(geospatial) 索引半径查问。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘长久化(persistence), 并通过 Redis哨兵(Sentinel)和主动 分区(Cluster)提供高可用性(high availability)。 反对那几种数据结构?字符串(string)、散列(hsahes)、列表(lists)、汇合(sets)、有序汇合(sorted sets). Redis读写速度:读11.2万/秒 写:8.6万/秒装置Redis(www.redis.cn 有中文网)1)在Redis根目录下执行命令2)装置 make3) 启动make install 装置后须要批改配置文件:4)批改redis根目录下的redis.conf文件a.去除IP绑定b.批改保护模式c.开启后盾启动 Redis服务器命令留神:Redis服务运行时,必须依赖于配置文件redis.conf.操作redis时最好在根目录中操作.1)启动redisredis-server redis.conf 2)进入redis客户端redis-cli -p 6379 (9379是缓存服务器默认的端口号)如果是本机服务也能够写成 redis-clictrl+c退出客户端 3)敞开redis服务器查出过程:ps -ef | grep redis终结过程:kill -9 XXXX kill XXXX 也能够间接用 redis-cli -p 6379 shutdown指令敞开服务器 Redis命令String 类型 Hash类型 List类型阐明:Redis中的List汇合是双端循环列表,别离能够从左右两个方向出入数据.List汇合能够当做队列应用,也能够当做栈应用队列:存入数据的方向和获取数据的方向相同栈:存入数据的方向和获取数据的方向雷同 Redis事务命令阐明:redis中操作能够增加事务的反对.一项工作能够由多个redis命令实现,如果有一个命令失败导致入库失败时.须要实现事务回滚. Redis高级利用redis入门案列1、增加jar包文件 ...

December 7, 2020 · 1 min · jiezi

关于redis:一万字详解-Redis-Cluster-Gossip-协议

Redis Cluster Gossip 协定明天来讲一下 Reids Cluster 的 Gossip 协定和集群操作,文章的思维导图如下所示。 集群模式和 Gossip 简介对于数据存储畛域,当数据量或者申请流量大到肯定水平后,就必然会引入分布式。比方 Redis,尽管其单机性能非常优良,然而因为下列起因时,也不得不引入集群。 单机无奈保障高可用,须要引入多实例来提供高可用性单机可能提供高达 8W 左右的QPS,再高的QPS则须要引入多实例单机可能反对的数据量无限,解决更多的数据须要引入多实例;单机所解决的网络流量曾经超过服务器的网卡的上限值,须要引入多实例来分流。有集群,集群往往须要保护肯定的元数据,比方实例的ip地址,缓存分片的 slots 信息等,所以须要一套分布式机制来保护元数据的一致性。这类机制个别有两个模式:分散式和集中式 分散式机制将元数据存储在局部或者所有节点上,不同节点之间进行一直的通信来保护元数据的变更和一致性。Redis Cluster,Consul 等都是该模式。 而集中式是将集群元数据集中存储在内部节点或者中间件上,比方 zookeeper。旧版本的 kafka 和 storm 等都是应用该模式。 两种模式各有优劣,具体如下表所示: 模式长处毛病集中式数据更新及时,时效好,元数据的更新和读取,时效性十分好,一旦元数据呈现了变更,立刻就更新到集中式的内部节点中,其余节点读取的时候立刻就能够感知到;较大数据更新压力,更新压力全副集中在内部节点,作为单点影响整个零碎分散式数据更新压力扩散,元数据的更新比拟扩散,不是集中某一个节点,更新申请比拟扩散,而且有不同节点解决,有肯定的延时,升高了并发压力数据更新提早,可能导致集群的感知有肯定的滞后 分散式的元数据模式有多种可选的算法进行元数据的同步,比如说 Paxos、Raft 和 Gossip。Paxos 和 Raft 等都须要全副节点或者大多数节点(超过一半)失常运行,整个集群能力稳固运行,而 Gossip 则不须要半数以上的节点运行。 Gossip 协定,顾名思义,就像风言风语一样,利用一种随机、带有传染性的形式,将信息流传到整个网络中,并在肯定工夫内,使得零碎内的所有节点数据统一。对你来说,把握这个协定不仅能很好地了解这种最罕用的,实现最终一致性的算法,也能在后续工作中得心应手地实现数据的最终一致性。 Gossip 协定又称 epidemic 协定(epidemic protocol),是基于流行病传播方式的节点或者过程之间信息替换的协定,在P2P网络和分布式系统中利用宽泛,它的方法论也特地简略: 在一个处于有界网络的集群里,如果每个节点都随机与其余节点替换特定信息,通过足够长的工夫后,集群各个节点对该份信息的认知终将收敛到统一。这里的“特定信息”个别就是指集群状态、各节点的状态以及其余元数据等。Gossip协定是完全符合 BASE 准则,能够用在任何要求最终一致性的畛域,比方分布式存储和注册核心。另外,它能够很不便地实现弹性集群,容许节点随时高低线,提供快捷的失败检测和动静负载平衡等。 此外,Gossip 协定的最大的益处是,即便集群节点的数量减少,每个节点的负载也不会减少很多,简直是恒定的。这就容许 Redis Cluster 或者 Consul 集群治理的节点规模能横向扩大到数千个。 Redis Cluster 的 Gossip 通信机制Redis Cluster 是在 3.0 版本引入集群性能。为了让让集群中的每个实例都晓得其余所有实例的状态信息,Redis 集群规定各个实例之间依照 Gossip 协定来通信传递信息。 ...

December 7, 2020 · 9 min · jiezi

关于redis:给你一个亿的keysRedis如何统计

前言不知你大规模的用过Redis吗?还是仅仅作为缓存的工具了?在Redis中应用最多的就是汇合了,举个例子,如下场景: 签到零碎中,一天对应一系列的用户签到记录。电商零碎中,一个商品对应一系列的评论。交友零碎中,某个用户的一系列的好友。Redis中汇合的特点无非是一个Key对应一系列的数据, 然而数据的作用往往是为了统计的,比方: 交友零碎中,须要统计每天的新增好友,以及单方的独特好友。电商零碎中,须要统计评论列表中的最新评论。签到零碎中,须要统计间断一个月的签到的用户数量。大型互联网利用中,数据量是微小的,少说百万,千万,甚至是一个亿,比方电商巨头淘宝,交友巨头微信、微博;办公巨头钉钉等,哪一个的用户不是上亿? 只有针对不同场景,抉择适合的汇合,统计能力更不便。 聚合统计聚合统计指的是多个元素聚合的后果,比方统计多个汇合的交加、并集、差集 在你须要对多个汇合做聚合统计的时候,Set汇合是个不错的抉择,除了其中无反复的数据外,Redis还提供了对应的API 交加在上述的例子中交友零碎中统计单方的独特好友正是聚合统计中的交加。 在Redis中能够userid作为key,好友的userid作为value,如下图: 统计两个用户的独特好友只须要两个Set汇合的交加,命令如下; `SINTERSTORE userid:new userid:20002 userid:20003` 上述命令运行实现后,userid:new这个key中存储的将是userid:20002、userid:20003两个汇合的交加。 差集举个例子:假如交友零碎中须要统计每日新增的好友,此时就须要对邻近两天的好友汇合取差集了,比方2020/11/1日的好友是set1,2020/11/2日的好友是set2,此时只须要对set1和set2做差集。 此时的构造应该如何设计呢?如下图: userid:20201101这个key记录了userid用户的2020/11/1日的好友汇合。 差集很简略,只须要执行SDIFFSTORE命令,如下: SDIFFSTORE  user:new  userid:20201102 userid:20201101 执行结束,此时的user:new这汇合将是2020/11/2日新增的好友。 这里还有一个更贴切的例子,微博上有个可能意识的人性能,能够应用差集,即是你敌人的好友减去你们独特的好友即是可能意识的人。 并集还是差集的那个例子,假如须要统计2020/11/01和2020/11/2总共新增的好友,此时只须要对这两日新增好友的汇合做一个并集。命令如下: `SUNIONSTORE  userid:new userid:20201102 userid:20201101` 此时新的汇合userid:new则是两日新增的好友。 总结Set汇合的交差并的计算复杂度很高,如果数据量很大的状况下,可能会造成Redis的阻塞。 那么如何躲避阻塞呢?倡议如下: 在Redis集群当选一个从库专门负责聚合统计,这样就不会阻塞主库和其余的从库了将数据交给客户端,由客户端进行聚合统计。排序统计在一些电商网站中能够看到商品的评论总是最新的在下面,这个是怎么做的呢? 最新评论列表蕴含了所有的评论,这就要汇合对元素进行保序存储了。也就是说汇合中的元素必须按序存储,称之为有序汇合。 Redis中的四种汇合中List和Sorted Set属于有序汇合。 然而List和Sorted Set有何区别呢?到底应用哪一种呢? List是依照元素进入程序进行排序,而Sorted Set能够依据元素权重来排序。 比方能够依据元素插入汇合的工夫确定权值,先插入的元素权重小,后插入的元素权重大。 针对这一例子中,显然这两种都是可能满足要求的,List中分页查问命令LRANGE和Sorted Set分页查问命令ZRANGEBYSCORE。 然而就灵活性来说,List必定不适宜,List只能依据先后插入的程序排序,然而大多数的场景中可能并不只是依照工夫先后排序,可能还会依照一些特定的条件,此时Sorted Set就很适合了,只须要依据独有的算法生成相应的权重即可。 二值状态统计二值状态指的是取值0或者1两种;在签到打卡的场景中,只须要记录签到(1)和未签到(0)两种状态,这就是典型的二值状态统计。 二值状态的统计能够应用Redis的扩大数据类型Bitmap,底层应用String类型实现,能够把它看成是一个bit数组。对于具体内容后续介绍......... 在签到统计中,0和1只占了一个bit,即便一年的签到数据才365个bit位。大大减少了存储空间。 Bitmap 提供了GETBIT/SETBIT 操作,应用一个偏移值 offset 对 bit 数组的某一个 bit 位进行读和写。不过,须要留神的是,Bitmap 的偏移量是从 0 开始算的,也就是说 offset 的最小值是 0。当应用 SETBIT 对一个 bit 位进行写操作时,这个 bit 位会被设置为 1。Bitmap 还提供了 BITCOUNT 操作,用来统计这个 bit 数组中所有1的个数。 ...

December 4, 2020 · 1 min · jiezi

关于redis:redis常见问题分析

1. 如何保障redis高可用和高并发redis主从架构,一主多从,能够满足高可用和高并发。呈现实例宕机主动进行主备切换,配置读写拆散缓解master读写压力。 2. redis高可用具体怎么施行倡议应用官网的哨兵机制,当主节点呈现故障,由Sentinel自定实现故障发现和转移,并告诉利用方,实现高可用性。 它次要有4个性能:集群监控:负责监控redis master和slave过程是否失常工作;音讯告诉:如果某个redis实例有故障,那么哨兵负责发送报警告诉给管理员;故障转移:如果master-node挂掉了,会主动转移到slave-node;配置核心:如果故障转移产生了,告诉client客户端新的master地址。3. 哨兵机制的原理通过sentinel模式启动redis后,主动监控master/slave运行状况。基本原理是:心跳检测和投票裁决。 每个sentinel会向其余sentinel、master、slave定时发送音讯,如果在指定工夫内没有回应,则临时认为对方宕机。 如果哨兵群组中少数sentinel都报告某一节点没有响应,才会认为该节点真正宕机。通过Raft投票算法,从剩下的slave节点中选出一台晋升为新的matser,而后主动批改相干配置。 4. redis哨兵部署须要留神什么至多3个实例,以保障群组的健壮性。 5. redis主从架构会失落数据吗?为什么异步复制导致的数据失落:因为master->slave数据复制是异步的,在异步复制前,如果master就宕机了,那前面行将复制的数据就失落了。脑裂导致的数据失落:某个master所在的机器脱离了失常的网络,导致slave连贯不上master,实际上master还在运行着。但哨兵认为master曾经失去连贯,并且从新选取了一个slave晋升为master,这会集群中就会呈现2个master节点。但client客户端还没来得及切换到新的master节点,依旧会把数据写入旧的master中。那当旧的master恢复正常的时候,会被当做一个slave节点挂倒新的master上面,原数据会被清空,从新从新的master复制一份数据。6. redis主从复制的原理一个slave实例,无论是第一次连贯还是重连到master,都会收回SYNC命令;master收到申请后,会做两件事:a)master执行BGSAVE,即在后盾保留数据到硬盘(rdb快照);b)master同时将新收到的写入和批改命令存入缓冲区(非查问类);master在将数据存入硬盘文件胜利后,将这个快照文件发送给slave,slave收到快照后会会清空内存,加载这个文件到内存中;master也会将缓冲区的命令,以redis命令协定的模式转发给slave,slave执行这些命令,实心和master的同步;master/slave尔后会一直通过异步的形式进行命令同步,达到最终的数据同步统一。7. redis过期策略有哪些惰性删除:当读/写一个曾经过期的key时,会触发惰性删除策略,间接删除掉这个过期的key;定期删除:因为惰性删除无奈保障冷数据及时删除,所以redis会定期被动淘汰一批过期数据;被动删除:以后已用内存超过maxMemory限定时,触发被动革除策略,被动删除的前提是设置了maxMemory的值。

December 4, 2020 · 1 min · jiezi

关于redis:一万字详解-Redis-Cluster-Gossip-协议

Redis Cluster Gossip 协定大家好,我是历小冰,明天来讲一下 Reids Cluster 的 Gossip 协定和集群操作,文章的思维导图如下所示。 集群模式和 Gossip 简介对于数据存储畛域,当数据量或者申请流量大到肯定水平后,就必然会引入分布式。比方 Redis,尽管其单机性能非常优良,然而因为下列起因时,也不得不引入集群。 单机无奈保障高可用,须要引入多实例来提供高可用性单机可能提供高达 8W 左右的QPS,再高的QPS则须要引入多实例单机可能反对的数据量无限,解决更多的数据须要引入多实例;单机所解决的网络流量曾经超过服务器的网卡的上限值,须要引入多实例来分流。有集群,集群往往须要保护肯定的元数据,比方实例的ip地址,缓存分片的 slots 信息等,所以须要一套分布式机制来保护元数据的一致性。这类机制个别有两个模式:分散式和集中式 分散式机制将元数据存储在局部或者所有节点上,不同节点之间进行一直的通信来保护元数据的变更和一致性。Redis Cluster,Consul 等都是该模式。 而集中式是将集群元数据集中存储在内部节点或者中间件上,比方 zookeeper。旧版本的 kafka 和 storm 等都是应用该模式。 两种模式各有优劣,具体如下表所示: 模式长处毛病集中式数据更新及时,时效好,元数据的更新和读取,时效性十分好,一旦元数据呈现了变更,立刻就更新到集中式的内部节点中,其余节点读取的时候立刻就能够感知到;较大数据更新压力,更新压力全副集中在内部节点,作为单点影响整个零碎分散式数据更新压力扩散,元数据的更新比拟扩散,不是集中某一个节点,更新申请比拟扩散,而且有不同节点解决,有肯定的延时,升高了并发压力数据更新提早,可能导致集群的感知有肯定的滞后分散式的元数据模式有多种可选的算法进行元数据的同步,比如说 Paxos、Raft 和 Gossip。Paxos 和 Raft 等都须要全副节点或者大多数节点(超过一半)失常运行,整个集群能力稳固运行,而 Gossip 则不须要半数以上的节点运行。 Gossip 协定,顾名思义,就像风言风语一样,利用一种随机、带有传染性的形式,将信息流传到整个网络中,并在肯定工夫内,使得零碎内的所有节点数据统一。对你来说,把握这个协定不仅能很好地了解这种最罕用的,实现最终一致性的算法,也能在后续工作中得心应手地实现数据的最终一致性。 Gossip 协定又称 epidemic 协定(epidemic protocol),是基于流行病传播方式的节点或者过程之间信息替换的协定,在P2P网络和分布式系统中利用宽泛,它的方法论也特地简略: 在一个处于有界网络的集群里,如果每个节点都随机与其余节点替换特定信息,通过足够长的工夫后,集群各个节点对该份信息的认知终将收敛到统一。这里的“特定信息”个别就是指集群状态、各节点的状态以及其余元数据等。Gossip协定是完全符合 BASE 准则,能够用在任何要求最终一致性的畛域,比方分布式存储和注册核心。另外,它能够很不便地实现弹性集群,容许节点随时高低线,提供快捷的失败检测和动静负载平衡等。 此外,Gossip 协定的最大的益处是,即便集群节点的数量减少,每个节点的负载也不会减少很多,简直是恒定的。这就容许 Redis Cluster 或者 Consul 集群治理的节点规模能横向扩大到数千个。 Redis Cluster 的 Gossip 通信机制Redis Cluster 是在 3.0 版本引入集群性能。为了让让集群中的每个实例都晓得其余所有实例的状态信息,Redis 集群规定各个实例之间依照 Gossip 协定来通信传递信息。 ...

December 3, 2020 · 9 min · jiezi

关于redis:跟随杠精的视角一起来了解Redis的主从复制

不想弹好吉他的撸铁狗,都不是好的程序猿尽管说单机的Redis性能很好,也有齐备的长久化机制,那如果你的业务体量真的很大,超过了单机可能承载的下限了怎么办?不做任何解决的话Redis挂了怎么办?带着这个问题开始咱们明天的主题-Redis高可用,因为篇幅起因,本章就只聊聊主从复制。 为啥要先从主从复制开始聊,是因为主从复制能够说是整个Redis高可用实现的基石,你能够先有这么一个概念,至于具体为什么是基石,这个前面聊到Sentinel和Redis集群的时候会说到。 首先咱们须要晓得,对于咱们开发人员来说,为什么须要主从架构?一个Redis实例难道不行吗? 其实除了开篇提到的负载超过了Redis单机可能解决的下限,还有一种状况Redis也无奈保障本身的高可用性。那就是即使Redis可能扛住所有流量,然而如果这个Redis过程所在的机器挂了呢?申请会间接调转枪口,大量的流量会霎时把你的DB打挂,而后你就能够背个P0,打包回家了。 而且,假如你对Redis的需要真的超过了单机的容量,你怎么办?搞多台独立的Redis实例吗?那如果用户缓存的数据这一次存在了实例一,下一次如果用户又拜访到了实例二,难道又要去走一遍DB吗?除非你可能保护好用户和Redis实例的对应关系(然而通常这样的逻辑比较复杂),否则部署多个Redis实例也就失去了它的意义,没有方法做到横向扩大了。 那换成主从架构就能解决这个问题吗?咱们能够从一个图来直观的理解一下。 在主从同步中,咱们将节点的角色划分为master和slave,造成一主多从。slave对外提供读操作,而master负责写操作,造成一个读写拆散的架构,这样一来就可能承载更多的业务申请。 在少数的业务场景下,对于Redis的读操作都要多于写操作,所以当读申请量特地大的时候,咱们能够通过减少slave节点来使Redis扛住更多的流量。 你这不行啊老弟,你往master写数据,那我要是连贯到slave下来了,不就拿不到之前的数据了?我这个小标题的不是写了吗?主从复制,slave会依照某种策略从master同步数据。Redis中咱们能够通过slaveof命令让一个Redis实例去复制(replicate)另外一台Redis的状态。被复制的Redis实例就是master节点,而执行slaveof命令的机器就是slave节点。 Redis的主从复制分为两个步骤,别离是同步和命令流传。 同步操作用于将Master节点内存状态复制给Slave节点,而命令流传则是在同步时,客户端又执行了一些写操作扭转了服务器的状态,此时master节点的状态与同步操作执行的时候不统一了,所以须要命令流传来使master和slave状态从新统一。 同步的大抵的流程如下: slave节点向master节点发送sync命令master收到sync命令之后会执行bgsave命令,Redis会fork出一个子过程在后盾生成RDB文件,同时将同步过程中的写命令记录到缓冲区中文件生成后,master会把RDB文件发送给slave,从服务器接管到RDB文件会将其载入内存而后master将记录在缓冲区的所有写命令发送给slave,slave对这些命令进行重放,将其数据库的状态更新至和master统一为了让大家更加清晰的意识到这个过程,咱们通过图再来理解一下。 ????????,那如果同步完了之后slave又挂了咋办?slave重启之后很可能就又跟maste不统一了?确实是这样,这就波及到一个名词叫断点续传了。下面探讨的是slave第一次连贯到master,会执行全量复制,而针对下面这种状况,Redis新老版本解决形式不一样。 Redis2.8之前,当主从实现了同步之后,slave如果断线重连,向master发送sync命令,master会将全量的数据再次同给slave。 然而咱们会发现一个问题,就是大部分数据都是有序的,再次全量同步显得没有必要。而在 Redis2.8之后,为了解决这个问题,便应用了psync命令来代替sync。 简略来说psync命令就是将slave断线期间master接管到的写命令全副发送给slave,slave重放之后状态便与master统一了。 呵呵,就这?那你晓得psync具体怎么实现的吗?还是说就只会用用?psync的实现依赖于主从单方独特保护的offset偏移量。 每次master向slave进行命令流传,流传了多少个字节的数据,就将本人的offset加上流传的字节数。而slave每次收到多少字节的数据,也会同样的更新本人的offset。 基于offset,只须要简略的比对就晓得以后主从的状态是否是统一的了,而后基于offset,将对应偏移量所对应的指令流传给slave重放即可。所以即便同步的时候slave挂掉了,基于offset,也能达到断点续传的成果。 不是吧不是吧,那master也挂了呢?你slave重新启动之后master的数据也更新了,依照你的说法,这两永远不可能达到数据统一了这个问题Redis确实也有想到,实际上除了offset之外,slave断线重连之后还会带上上一个master的实例的runid,每个服务实例都有本人的惟一的runid,只有Redis服务重启,其runid就会产生扭转。 master收到这个runid之后会判断是否与本人以后的runid统一,如果统一阐明断线之前还是与本人建设的连贯,而如果不统一就阐明slave断线期间,master也产生了宕机,此时就须要将数据全量同步给slave了。 就算你能解决这个问题,然而你就保护了一个偏移量,偏移量对应的命令从哪儿来?天上掉下来吗?我哪儿晓得这些命令是啥?确实,咱们须要通过这个offset去拿到真正须要的数据—也就是指令,而Redis是通过复制积压缓冲区来实现的。 名字高大上,实际上就是一队列。就跟什么递归、轮询、透传一样,听着高大上,实际上简略的一匹。言归正传,复制积压缓冲区的默认大小为1M,Redis在进行命令流传时,除了将写命令发送给slave,还会将命令写到复制积压缓冲区内,并和以后的offset关联起来。这样一来就可能通过offset获取到对应的指令了。 然而因为缓冲区的大小无限,如果slave的断线工夫太久,复制积压缓冲区内早些时候的指令就曾经被新的指令笼罩掉了,此处能够了解为一个队列,早些时候入队的元素曾经被出队了。 因为没有绝对应的offset了,也就无奈获取指令数据,此时Redis就会进行全量同步。当然,如果offset还存在于复制积压缓冲区中,则依照对应的offset进行局部同步。 基于以上的全量、增量的主从复制,可能在master呈现故障的状况下,进行主从的切换,保障服务的失常运行。除此之外还能解决异常情况下数据失落的问题。基于读写拆散的策略还可能进步整个Redis服务的并发量。 可别吹了,你说的这个什么主从复制就没啥毛病吗?其实是有的,例如刚刚提到的主从的切换,如果不必现成的HA框架,这个过程须要程序员本人手动的实现,同时告诉服务调用方Redis的IP产生了变动,这个过程能够说是非常的简单,甚至还可能波及到代码配置的改变。而且之前的slave复制的可都是挂掉的master,还得去slave上更改其复制的主库,就更加简单了。 除此之外,尽管实现了读写拆散,然而因为是一主多从的架构,集群的读申请能够扩大,然而写申请的并发是有下限的,那就是master可能扛住的下限,这个没有方法扩大。 好了,本期的分享就到此结束了,咱们下期再见。 如果你感觉这篇文章对你有帮忙,还麻烦点个赞,关个注,分个享,留个言 也能够微信搜寻公众号【SH的全栈笔记】,关注公众号提前浏览其余的文章 往期文章 Redis根底—分析根底数据结构及其用法Redis根底—理解Redis是如何做数据长久化的简略理解一下K8S,并搭建本人的集群WebAssembly齐全入门——理解wasm的前世今生浅谈JVM与垃圾回收

December 1, 2020 · 1 min · jiezi

关于redis:面试官问redis分布式锁如何设计才能让他满意

前言 对于分布式锁的问题我也查过很多材料,感觉很多形式实现的并不欠缺,或者看着云里雾里的,不知所以然,于是就整顿了这篇文章,心愿对您有用,有写的不对的中央,欢送留言斧正。 首先咱们来聊聊什么是分布式锁,到底解决了什么问题?间接看代码 $stock = $this->getStockFromDb();//查问残余库存 if ($stock>0){ $this->ReduceStockInDb(); // 在数据库中进行减库存操作 echo "successful"; }else{ echo "库存有余"; }很简略的一个场景,用户下单,咱们查问商品库存够不够,不够的话间接返回库存有余相似的错误信息,如果库存够的话间接在数据库中库存-1,而后返回胜利,在业务逻辑上这段代码是没有什么问题的。 然而,这段代码是存在重大的问题的。 如果库存只剩 1,并且在并发比拟高的状况下,比方两个申请同时执行了这段代码,同时查到库存为 1,而后顺利成章的都去数据库执行 stock-1 的操作,这样库存就会变成-1,而后就会引发超卖的景象,方才说的是两个申请同时执行,如果同时几千个申请打过去,可见造成的损失是十分大的。于是呢有些聪明人就想了个方法,方法如下。 大家都晓得 redis 有个 setnx 命令,不晓得的话也没关系,我曾经帮你查过了 咱们把下面的代码优化一下 version-1 $lock_key="lock_key"; $res = $redis->setNx($lock_key, 1); if (!$res){ return "error_code"; } $stock = $this->getStockFromDb();//查问残余库存 if ($stock>0){ $this->ReduceStockInDb(); // 在数据库中进行减库存操作 echo "successful"; }else{ echo "库存有余"; }$redis->delete($lock_key);第一次申请进来会去 setNx,当然后果是返回 true,因为 lock_key 不存在,而后上面业务逻辑失常进行,工作执行完了之后把lock_key删除掉,这样下一次申请进来反复上述逻辑第二次申请进来同样会去执行 setNx,后果返回 false,因为lock_key曾经存在,而后间接返回错误信息(你双11抢购秒杀产品的时候给你返回的零碎忙碌就是这么来的),不执行库存减 1 的操作有的同学可能有纳闷,咱们不是说高并发的状况下么?要是两个申请同时 setNx 的话获取的后果不都是 true 了,同样会同时去执行业务逻辑,问题不是一样没解决么?然而大家要明确 redis 是单线程的,具备原子性,不同的申请执行 setnx 是程序执行的,所以这个是不必放心的。看似问题解决了,其实并不然。 ...

December 1, 2020 · 2 min · jiezi

关于redis:基础知识redis详解Foam番茄

Redis学习形式: 上手就用根本的实践先学习,而后将常识融汇贯通nosql解说为什么要用Nosql 当初都是大数据时代 大数据个别的数据库无奈进行剖析解决了 至多要会Springboot+SpringCloud 压力肯定会越来越大,适者生存 1.单机MySQL的年代 90年代,一个根本的网站访问量个别不会太大,单个数据库齐全足够,那个时候,更多的去应用动态网页,HTML,服务器基本没有太大的压力思考一下,这种状况下:整个网站的瓶颈是什么? 1.数据量如果太大,一个机器放不下了 2.数据的索引 300万就肯定要建设索引(B+Tree),一个机器内存也放不下 3.访问量(读写混合),一个服务器接受不了 只有你呈现以上的三种状况之一,那么你就必须要升级 2.Memcached(缓存)+MYSQL+垂直拆分 网站80%的状况都是在读,每次都要去查詢数据库的话就非常的麻烦!所以说咱们心愿加重数据的压力,咱们能够应用缓存来保障效率!倒退过程:优化数据结构和索引->文件缓存(IO)->Memcachaed(过后最热门的技术!) 3.分库分表+程度分表+MYSQL集群 技术和业务在倒退的同时,对人的要求也越来越高!==实质:数据库(读,写)== 早些年MYISAM:表锁,非常影响效率!高并发下就会呈现重大的锁问题 转战INNODB:行锁 缓缓的就开始应用分库分表来解决写的压力!Mysql在那个年代推出了表分区!这个并没有多少公司应用! Mysql的集群,很好的解决了那个年代的所有需要 4.现在最近的年代 技术爆炸 2010(按键手机 android1.0HTC)--2020 十年之间,世界曾经产生了天翻地覆的变动(定位,也是一种数据,音乐,热榜!) MySQL等关系型数据库就不够用了,数据量很多,变动很快! 图形数据库 JSON数据库 MYSQL有的时候应用它来存储一些比拟大的文件,博客,图片!数据库表很大,效率就低了!如果有一种数据库来专门解决这种数据,mysql的压力就会变得非常小(钻研如何解决这些问题!)大数据的io压力下,表简直没法更大 目前一个根本的互联网我的项目 为什么要用NoSQL 用户的个人信息,社交网络,==地理位置==。用户本人产生的数据,用户日志等等爆发式增长! 这时候咱们就须要应用NoSQL数据库的,NoSQL能够很好的解决以上的状况! NoSQL=Not Only SQL(不仅仅是SQL) 泛指非关系型数据库,随着web2.0互联网的诞生!传统的关系型数据库很难凑合web2.0时代!尤其是超大规模的高并发的社区!站长!裸露进去很多难以克服的问题,NOSQL在当今大数据环境下倒退的十分迅速,Redis是倒退最快的,而且是咱们当下必须把握的技术! 很多的数据类型用户的个人信息,社交网络,地理位置。这些数据类型的存储不须要一个固定的格局(行和列),不须要有多余的操作就能够横向扩大了!Map<String,Object>应用键值对来管制 NoSql特点 1.不便扩大(数据之间没有关系,很好扩大!) 2.大数据量高性能(Redis一秒能够写8万次,读取11万次,nosql的缓存记录级,是一种细粒度的缓存,性能比拟高) 3.数据类型是多样型的!(不须要当时设计数据库!随取随用!如果是数据量非常大的表,很多人就无奈设计了!) 4.传统RDBMS和NOSQL 传统的RDBMS 结构化组织SQL数据和关系都存在独自的表中操作操作,数据定义语言严格的一致性根底的事务……NOSQL 不仅仅是数据没有固定的查询语言键值对存储,列存储,文档存储,图形数据库(社交关系)最终一致性CAP定理 和 BASE实践(异地多活!)高级架构师高性能,高可用,高可扩……理解:3V+3高 大数据时代的3v:次要是形容问题的 1.海量Volume 2.多样Variety 3.实时Velocity 大数据时代的3高:次要是对程序的要求 1.高并发 2.高可拓(随时程度拆分,机器不够了,能够扩大机器) 3.高性能(保障用户体验和性能!) 真正在公司中的实际:NOsql+RDBMS一起应用才是最强的,阿里巴巴的架构演进! 技术没有高下之分,看你如何应用!(晋升内功,思维的进步!) 技术急不得,越是缓缓学,能力越扎实 麻利开发,极限编程 任何一家互联网的公司,都不可能只是简简单单让用户能用就好了 大量公司做的都是雷同的业务(竞品协定) 随着这样的竞争,业务是越来越欠缺,而后对于开发者的要求也是越来越高! ...

November 28, 2020 · 7 min · jiezi

关于redis:分布式电商项目七Redis缓存下

Redis长久化策略什么是长久化阐明:Redis运行环境在内存中,如果redis服务器敞开,则内存数据将会失落.需要: 如何保留内存数据呢?解决方案: 能够定期将内存数据长久化到磁盘中.长久化策略规定:当redis失常运行时,定期的将数据保留到磁盘中,当redis服务器重启时,则依据配置文件中指定的长久化的形式,实现数据的复原.(读取数据,之后复原数据.) RDB模式RDB模式特点阐明1).RDB模式是Redis默认的策略.2).RDB模式可能定期(工夫距离)长久化. 弊病:可能导致数据的失落.3).RDB模式记录的是内存数据的快照.长久化效率较高. 快照只保留最新的记录. RDB模式命令1.save命令: 将内存数据长久化到磁盘中 被动的操作 会造成线程阻塞2.bgsave命令: 将内存数据采纳后盾运行的形式,长久化到文件中. 不会造成阻塞.3.默认的长久化的机制save 900 1 如果在900秒内,执行了1次更新操作,则长久化一次save 300 10 如果在300秒内,执行了10次更新操作,则长久化一次save 60 10000 如果在60秒内,执行了10000次更新操作,则长久化一次 长久化文件配置1).指定长久化文件2).指定长久化文件目录 AOF模式AOF模式特点1).AOF模式默认条件下是敞开的.须要手动开启2).AOF模式记录的是用户的操作过程,所以能够实现实时长久化操作.3).AOF模式因为记录的是实时的操作过程,所以长久化文件较大.须要定期维护. 启动AOF模式阐明:如果一旦开启AOF模式,则以AOF模式为准. 对于长久化操作总结1.当内存数据容许大量失落时,采纳RDB模式 (快)2.当内存数据不容许失落时,采纳AOF模式(定期维护长久化文件)3.个别在工作中采纳 RDB+AOF模式独特作用,保证数据的有效性. 面试题问题: 如果小李(丑陋妹子)在公司服务器中执行了flushAll命令,问怎么办?答: 须要找到aof文件之后,删除flushAll命令 之后重启redis,执行save命令即可. 内存优化策略为什么须要内存优化阐明: 因为redis在内存中保留数据.如果始终存储,则内存数据必然溢出.所以须要定期维护内存数据的大小.保护策略: 删除旧的不必的数据,保留新的罕用的数据 LRU算法(设置上次至今的范畴间隔时间t,筛选t最大的删除)LRU是Least Recently Used的缩写,即最近起码应用,是一种罕用的页面置换算法,抉择最近最久未应用的页面予以淘汰。该算法赋予每个页面一个拜访字段,用来记录一个页面自上次被拜访以来所经验的工夫 t,当须淘汰一个页面时,抉择现有页面中其 t 值最大的,即最近起码应用的页面予以淘汰。计算维度: 工夫T注意事项: LRU算法是迄今为止内存中最好用的数据置换算法. LFU算法(设置应用次数num,为了将一些很久不实用但之前应用次数很多的数据筛选,所以,num数当很久不被援用时依照指数衰减即,定时右移一位。最初筛选num数最小的删除)LFU(least frequently used (LFU) page-replacement algorithm)。即最不常常应用页置换算法,要求在页置换时置换援用计数最小的页,因为常常应用的页应该有一个较大的援用次数。然而有些页在开始时应用次数很多,但当前就不再应用,这类页将会长工夫留在内存中,因而能够将援用计数寄存器定时右移一位,造成指数衰减的均匀应用次数。维度: 应用次数 随机算法(随机筛选删除)随机算法. TTL算法(依据存活工夫筛选存活工夫最小的,提前删除)依据残余的存活工夫,将马上要超时的数据提前删除. 配置内存优化策略(redis.conf文件的570行~600行设置)1.volatile-lru 在设定了超时工夫的数据中,采纳lru算法2.allkeys-lru 在所有的数据中,采纳lru算法3.volatile-lfu 在设定了超时工夫的数据中,采纳lfu算法4.allkeys-lfu 所有数据采纳lfu算法5.volatile-random 设置超时工夫数据的随机算法6.allkeys-random 所有数据的随机7.volatile-ttl 将设定了超时工夫的数据,提前删除.8.noeviction 默认规定 如果设定noeviction 则不删除数据,间接报错返回. 手动批改redis内存优化策略: 对于缓存面试问题问题出发点:因为缓存生效,导致大量的用户的申请,间接拜访数据库服务器.导致负载过高,从而引发整体宕机的危险!!! 缓存穿透(拜访数据库中没有的数据,所以每次redis中都无奈命中,间接拜访数据库,可能威逼到数据库)阐明: 用户频繁拜访数据库中不存在的数据,可能呈现缓存穿透的景象.如果该操作是高并发操作,则可能间接威逼数据库服务器.解决方案:1.采纳IP限流的形式 升高用户拜访服务器次数. IP动静代理(1分钟变一次)2.微服务的解决形式: 利用断路器返回执行的业务数据即可不执行数据库操作 从而爱护了数据库.3.微服务解决形式: API网关设计. 不容许做非法操作 ...

November 28, 2020 · 3 min · jiezi

关于redis:分布式电商项目六Redis缓存上

Redis缓存学习优化现有架构阐明:通过缓存服务器能够无效的晋升用户的拜访的效率.注意事项:1.缓存的数据结构 应该选用 K-V构造 只有key惟一 那么后果必然雷同…2.缓存中的数据不可能始终存储,须要定期将内存数据进行优化 LRU算法…3.缓存要求运行速度很快, C语言实现… 运行在内存中.4.如果缓存运行的数据在内存中,如果断电/宕机,则内存数据间接失落. 实现内存数据的长久化操作(磁盘). Redis缓存服务器网址: http://www.redis.cn/ Redis介绍Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它能够用作数据库、缓存和消息中间件。 它反对多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 汇合(sets), 有序汇合(sorted sets) 与范畴查问, bitmaps, hyperloglogs 和 天文空间(geospatial) 索引半径查问。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘长久化(persistence), 并通过 Redis哨兵(Sentinel)和主动 分区(Cluster)提供高可用性(high availability)。nginx: 3-5万/秒redis: 读: 11.2万/秒 写: 8.6万/秒 均匀10万/秒吞吐量: 50万/秒 Redis装置1).解压redis文件2).挪动文件/批改文件3).装置Redis命令1: make --C语言编写的须要编译成二进制文件运行命令2: make install --编译实现后装置 批改redis.conf配置文件(通过辅助软件MobaXterm)1.批改IP绑定2.敞开保护模式3.开启后盾启动 批改Redis的配置文件(通过命令模式)命令1: 展示行号 :set nu![Image \[1\].png](/img/bVcIDmr)批改地位1: 正文IP绑定![Image \[2\].png](/img/bVcIDmq)批改地位2: 敞开保护模式![Image \[3\].png](/img/bVcHYr7)批改地位3: 开启后盾启动![Image \[4\].png](/img/bVcHYse) Redis命令1.启动redis redis-server redis.conf须要用到配置信息的启动形式(redis—server启动示意恪守默认配置启动,则只能在本机应用不能外联)2.查看redis服务项3.进入redis客户端 ...

November 28, 2020 · 6 min · jiezi

关于redis:Redis-备份容灾及高可用实战

Redis曾经大量利用于各种互联网架构场景中,其优异的性能,良好的操作性,以及大量的场景利用案例,使得Redis备受瞩目。本文作者向大家介绍了一种Redis在非大集群分布式应用场景下的灾备解决方案。一起来品读一下吧~一,Redis简略介绍Redis是一个高性能的key-value非关系型数据库,因为其具备高性能的个性,反对高可用、长久化、多种数据结构、集群等,使其怀才不遇,成为罕用的非关系型数据库。此外,Redis的应用场景也比拟多。 会话缓存(Session Cache)Redis缓存会话有十分好的劣势,因为Redis提供长久化,在须要长时间放弃会话的利用场景中,如购物车场景这样的场景中能提供很好的长会话反对,能给用户提供很好的购物体验。全页缓存在WordPress中,Pantheon提供了一个不错的插件wp-redis,这个插件能以最快的速度加载你已经浏览过的页面。队列Reids提供list和set操作,这使得Redis能作为一个很好的音讯队列平台来应用。咱们常通过Reids的队列性能做购买限度。比方到节假日或者推广期间,进行一些流动,对用户购买行为进行限度,限度明天只能购买几次商品或者一段时间内只能购买一次。也比拟适宜实用。 排名Redis在内存中对数字进行递增或递加的操作实现得十分好。所以咱们在很多排名的场景中会利用Redis来进行,比方小说网站对小说进行排名,依据排名,将排名靠前的小说举荐给用户。公布/订阅Redis提供公布和订阅性能,公布和订阅的场景很多,比方咱们能够基于公布和订阅的脚本触发器,实现用Redis的公布和订阅性能建设起来的聊天零碎。此外还有很多其它场景,Redis都体现的不错。 二,Redis应用中单点故障问题正是因为Redis具备多种低劣特新,且利用场景十分丰盛,以至于Redis在各个公司都有它存在的身影。那么随之而来的问题和危险也就来了。Redis尽管利用场景丰盛,但局部公司在实际Redis利用的时候还是绝对激进应用单节点部署,那为日后的保护带来了平安危险。 在2015年的时候,曾解决过一个因为单点故障起因导致的业务中断问题。过后的Redis都未采纳分布式部署,采纳单实例部署,并未思考容灾方面的问题。 过后咱们通过Redis服务器做用户购买优惠商品的行为管制,但起初因为未知起因Redis节点的服务器宕机了,导致咱们无奈对用户购买行为进行管制,造成了用户可能在一段时间内屡次购买优惠商品的行为。 这种宕机事变能够说曾经对公司造成了不可挽回的损失了,平安危险问题十分重大,作为过后运维这个零碎的我来说有必要对这个问题进行修复和在架构上的改良。于是我开始了解决非分布式应用下Redis单点故障方面的钻研学习。 三,非分布式场景下Redis利用的备份与容灾Redis主从复制当初应该是很广泛了。罕用的主从复制架构有如下两种架构计划。 罕用Redis主从复制计划一这是最常见的一种架构,一个Master节点,两个Slave节点。客户端写数据的时候是写Master节点,读的时候,是读取两个Slave,这样实现读的扩大,加重了Master节点读负载。计划二这种架构同样是一个Master和两个Slave。不同的是Master和Slave1应用keepalived进行VIP转移。Client连贯Master的时候是通过VIP进行连贯的。防止了计划一IP更改的状况。Redis主从复制长处与有余长处实现了对master数据的备份,一旦master呈现故障,slave节点能够晋升为新的master,顶替旧的master持续提供服务实现读扩大。应用主从复制架构, 个别都是为了实现读扩大。Master次要实现写性能,  Slave实现读的性能有余架构计划一当Master呈现故障时,Client就与Master端断开连接,无奈实现写性能,同时Slave也无奈从Master进行复制。此时须要通过如下操作(假如晋升Slave1为Master): 1)在Slave1上执slaveof no one命令晋升Slave1为新的Master节点。2)在Slave1上配置为可写,这是因为大多数状况下,都将slave配置只读。3)通知Client端(也就是连贯Redis的程序)新的Master节点的连贯地址。4)配置Slave2从新的Master进行数据复制。架构计划二当master呈现故障后,Client能够连贯到Slave1上进行数据操作,然而Slave1就成了一个单点,就呈现了常常要防止的单点故障(single point of failure)。之后须要通过如下操作: 1)在Slave1上执行slaveof no one命令晋升Slave1为新的Master节点2)在Slave1上配置为可写,这是因为大多数状况下,都将Slave配置只读3)配置Slave2从新的Master进行数据复制能够发现,无论是哪种架构计划都须要人工干预来进行故障转移(failover)。须要人工干预就减少了运维工作量,同时也对业务造成了微小影响。这时候能够应用Redis的高可用计划-Sentinel 四,Redis Sentinel介绍Redis Sentinel为Redis提供了高可用计划。从实际方面来说,应用Redis Sentinel能够创立一个无需人为干涉就能够预防某些故障的Redis环境。Redis Sentinel设计为分布式的架构,运行多个Sentinel过程来独特单干的。运行多个Sentinel过程单干,当多个Sentinel同一给定的master无奈再持续提供服务,就会执行故障检测,这会升高误报的可能性。 五,Redis Sentinel性能Redis Sentinel在Redis高可用计划中次要作用有如下性能: 监控Sentinel会一直的查看master和slave是否像预期那样失常运行告诉通过API,Sentinel可能告诉系统管理员、程序监控的Redis实例呈现了故障主动故障转移如果master不像料想中那样失常运行,Sentinel能够启动故障转移过程,其中的一个slave会提成为master,其它slave会重新配置来应用新的master,应用Redis服务的应用程序,当连贯时,也会被告诉应用新的地址。配置提供者Sentinel能够做为客户端服务发现的认证源:客户端连贯Sentinel来获取目前负责给定服务的Redis master地址。如果产生故障转移,Sentinel会报告新的地址。六,Redis Sentinel架构 七,Redis Sentinel实现原理Sentinel集群对本身和Redis主从复制进行监控。当发现Master节点呈现故障时,会通过如下步骤: 1)Sentinel之间进行选举,选举出一个leader,由选举出的leader进行failover2)Sentinel leader选取slave节点中的一个slave作为新的Master节点。对slave选举须要对slave进行选举的办法如下: a) 与master断开工夫 如果与master断开的工夫超过down-after-milliseconds(sentinel配置) * 10秒加上从sentinel断定master不可用到sentinel开始执行故障转移之间的工夫,就认为该slave不适宜晋升为master。b) slave优先级每个slave都有优先级,保留在redis.conf配置文件里。如果优先级雷同,则持续进行。c) 复制偏移地位复制偏移纪录着从master复制数据复制到哪里,复制偏移越大表明从master承受的数据越多,如果复制偏移量也一样,持续进行选举d) Run ID选举具备最小Run ID的Slave作为新的Master流程图如下:3) Sentinel leader会在上一步选举的新master上执行slaveof no one操作,将其晋升为master节点4)Sentinel leader向其它slave发送命令,让残余的slave成为新的master节点的slave5)Sentinel leader会让原来的master降级为slave,当恢复正常工作,Sentinel leader会发送命令让其从新的master进行复制以上failover操作均有sentinel本人单独实现,齐全无需人工干预。总结应用sentinel实现了Redis的高可用,当master呈现故障时,齐全无需人工干预即可实现故障转移。防止了对业务的影响,进步了运维工作效率。在部署sentinel的时候,倡议应用奇数个sentinel节点,起码三个sentinel节点。 写在最初因为sentinel知识点比拟多,这里仅给大家进行介绍,让大家有个理解。 原文:https://www.sohu.com/a/167105...

November 25, 2020 · 1 min · jiezi

关于redis:Redis持久化

Redis有两种长久化计划,RDB(Redis DataBase)和AOF(Append Only File) 一、RDBredis的RDB计划是一种快照形式长久化,就是在某时刻把所有数据进行残缺备份。RDB是redis默认的长久化计划,它的作用是一旦在指定的工夫距离内,执行指定次数的写操作,redis服务会将内存中的数据写入磁盘中,默认是写入/var/lib/redis/dump.rdb 文件,redis重启会通过加载dump.rdb文件复原数据 1.从配置文件理解RDB关上 /etc/redis.conf 文件,找到SNAPSHOTTING局部内容 1. ################################ SNAPSHOTTING  ################################ 2. #   save <seconds> <changes> 3. # 上面第一行的意思是如果900内至多有一个键被改变,主动进行数据保留,若不想应用RDB长久化能够把所有 4. #save配置正文掉,或者增加一行 save "" 5. save 900 1 6. save 300 10 7. save 60 10000 9. # 若redis最近一次长久化到dump文件出错,则默认不容许进行写操作,改成no则忽视长久化谬误容许写操作 10. stop-writes-on-bgsave-error yes 12. # 压缩dump长久化文件,改成no不压缩文件会变大很多,不过能节一点cpu,倡议应用默认值yes 13. rdbcompression yes 15. #长久化文件校验,会耗费一些性能,倡议应用默认值yes 16. rdbchecksum yes 18. # RDB长久化文件名 19. dbfilename dump.rdb 21. # 长久化文件存储目录,即dump文件所在目录,aof文件也会放在这个目录下 22. dir /var/lib/redis 2.触发RDB快照的几种形式save         此命令是同步命令,在长久化时会阻塞所有客户端申请bgsave     异步命令,会生成一个子过程将内存数据保留到dump文件,不影响主过程服务。通过配置文件save属性触发的长久化也是通过bgsave形式保留,新建过程会耗费内存flushall     此命令在清空redis数据后会进行长久化操作shutdown  应用shutdown命令会先进行长久化操作再敞开服务 3.优缺点长处:  紧凑的繁多文件,实用于劫难复原  与aof相比,在复原大的数据集时,RDB形式会更快毛病:  RDB须要常常生成子过程来进行数据长久化,耗时、耗性能  数据完整性不高,依据配置,一旦产生redis意外宕机可能会失落几分钟的数据 二、aofredis的aof备份是一种写日志形式长久化,就是将用户所有的写指令备份到文件中,还原数据时会将所有指令从新执行一遍。redis默认不开启aof,redis中RDB和aof两种长久化形式能同时应用 1.aof重写因为aof的运作形式是一直将命令追加至文件的开端,随着写入命令的一直减少,aof文件体积会变得越来越大。比方,对一个计数器调用了100此incr,那仅仅为了保留一个值aof文件就须要应用100条记录。这样不止会造成aof文件体积过大,还会导致数据恢复时速度太慢。而实际上只用一条set命令就足以保留计数器以后值了。为了解决这种状况redis反对bgrewriteaof重写命令,用于异步执行aof文件重写操作,下面的100条记录变成1条。它会创立一个以后aof文件的优化版本,而即便bgrewriteaof执行失败,也不会有任何数据失落,因为旧的aof文件在bgrewriteaof胜利之前不会被批改。redis在肯定条件下会自发进行重写,也能够调用bgrewirteaof命令被动重写 2.从配置文件理解aof关上/etc/redis.conf 文件,找到 APPEND ONLY FILE 局部 ...

November 25, 2020 · 1 min · jiezi

关于redis:Redis简介

redis(Remote Dictionary Server)是一种开源的、反对网络、基于内存、可长久化的key-value数据库 劣势特点1.性能高,每秒十万左右读写速度2.丰盛的数据类型,key-value的value能够是String、List、Hash、Set、sorted set3.原子性,所有单操作都是原子性的4.丰盛的个性,公布/订阅、告诉、key过期等等 数据类型这里说的数据类型都是指,key-value中value的数据类型,redis就是一个key-value数据库。它的劣势在于value是多样的1.String:最根本的,二进制平安,最大512MB2.Hash:如果把redis设想成一个值能够是不同数据类型map。那么Hash就像是map中嵌一个map3.List:有序汇合4.Set:无序不反复汇合5.sorted set:有序不反复汇合。它的程序是通过给每个元素关联一个double类型的分数值实现的,值是惟一,分数能够反复 数据库redis是一个字典构造的存储服务器,一个redis实例提供多个用于存储的字典,客户端能够指定操作那个字典。这与关系型数据库实例中有多个数据库相似。能够通过批改配置文件中的database选项,设置redis数据库数量。默认16个,以0开始递增数字 命名。默认应用0号redis数据库与关系型数据库有很大区别。1.不反对自定义数据库名称。2.不反对为每个数据库设置不同明码。3.最重要的一个实例的多个数据库之间不是齐全隔离的,比方flushall命令能够清空redis实例中所有数据库中的数据。所以,其实这些数据库更像是一种命名空间,不适宜存储不同应用程序的数据 公布/订阅redis一个很好的中央就是,它把性能都设计的很容易应用,比方订阅公布:1.客户端应用subscribe channel[channel]命令订阅某几个频道,客户端进入阻断状态2.某个客户端应用publish channel message公布信息,所有订阅了这个频道的客户端都会收到此信息 事务1.multi开始事务2.编写命令退出事务队列中3.exec命令触发事务redis的事务执行并不是原子性的,它能够了解为一个打包的执行脚本,两头某条指令的失败不会导致后面已执行指令的回滚,也不会造成后续指令不做 管道技术redis是一种申请/响应模式的tcp服务,意思就是说,redis客户端向服务端发送一个申请,并监听socket返回。通常是以阻塞模式,期待服务器响应。redis管道技术就是,在服务端未响应时,客户端能够持续向服务端发送申请,并一次性获取所有申请的响应。管道技术能大大提高redis服务性能当短时间内产生大量申请,比方我的项目启动之初须要将大量初始化数据放入到redis中,能够思考应用管道技术 set命令的几个参数set key value [expiration EX seconds|PX milliseconds] [NX|XX]EX seconds:将键的过期工夫设置为seconds秒。执行SET key value EX seconds的成果等同于执行SETEX key seconds value。PX milliseconds:将键的过期工夫设置为milliseconds毫秒。执行SET key value PX milliseconds 的成果等同于执行PSETEX key milliseconds value。NX :只在键不存在时,才对键进行设置操作。执行SET key value NX的成果等同于执行 SETNX key valueXX :只在键曾经存在时,才对键进行设置操作。 在Redis 2.6.12版本以前,SET命令总是返回OK。从Redis 2.6.12版本开始,SET命令只在设置操作胜利实现时才返回OK;如果命令应用了NX或者XX选项,然而因为条件没达到而造成设置操作未执行,那么命令将返回空批量回复(nil) 罕用业务场景1.缓存,跟其余缓存比,很大的一个劣势,反对多种数据类型2.计数器,例如点赞数、珍藏、分享数等等等等这里不写

November 25, 2020 · 1 min · jiezi

关于redis:那些年我们用过的Redis还记得大明湖畔那些Redis数据吗

redis五种罕用的数据结构为string (字符串)、list (列表)、set (汇合)、hash (哈希) 和 zset (有序汇合)。小白易读,倡议珍藏。万丈高楼平地起reids是键值对构造的NoSql数据库,key都是字符串,常说的数据类型不同,说的都是value。redis所有的数据都会有一个dicEntry,泛滥dicEntry组成一个链表。上方那个sds就是key,能够看出是一个字符串。下方那个绿色的redisObject就是value。能够看出图中给的例子就是string类型。redisObject会指向实在的数据(比方图中的字符串“world”)。前面咱们说的数据类型特指value局部。 string (字符串)Redis 的字符串是动静字符串,是能够批改的字符串。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩容时一次只会多扩 1M 的空间。一个字符串最大能够接受512M。 罕用指令设置获取值127.0.0.1:6379> set name pjjltOK127.0.0.1:6379> get name"pjjlt"127.0.0.1:6379> exists name(integer) 1设置应用set,获取应用get,查看某key是否存在用exists。 设置过期工夫127.0.0.1:6379> setex company 10 gongsiOK127.0.0.1:6379> get company"gongsi"127.0.0.1:6379> get company(nil)能够在设置值的时候间接指定,keycompany能够存活10秒。此外,也能够将设置值和设置过期工夫离开,应用expire。 127.0.0.1:6379> set company gongsiOK127.0.0.1:6379> expire company 10(integer) 1127.0.0.1:6379> get company"gongsi"127.0.0.1:6379> get company(nil)保障不笼罩valueredis还提供了命令,在设置值的时候,如果发现key已存在,此次设置失败,保障原始value不被笼罩。应用setnx命令。 127.0.0.1:6379> setnx company gongsi(integer) 1# 能够看到第二次设置失败,返回值为 0.127.0.0.1:6379> setnx company haha(integer) 0127.0.0.1:6379> get company"gongsi"批量设置获取值127.0.0.1:6379> mset name pjjlt age 26 company gongsiOK127.0.0.1:6379> mget name age company1) "pjjlt"2) "26"3) "gongsi"批量设置应用mset,批量获取应用mget。批量设置获取,缩小IO,进步性能,你值得领有。 ...

November 22, 2020 · 4 min · jiezi

关于redis:那些年我们用过的RedisRedis集群搭建原来这么简单

Reids服务集群模式可分为主从、哨兵、Cluster模式。本博客次要介绍主从和Cluster模式三种集群模式简介主从模式:主从模式是三种模式中最简略的,个别有一个master服务和多个(至多一个)slave服务组成。次要实现读写拆散,加重单Redis服务压力。master负责写数据,而后将数据copy给slave,slave服务负责读数据。 哨兵模式:主从模式有个弊病,就是一旦master服务挂掉,Redis服务就无奈再写入数据,slave并不会降级为master。于是须要另外一种类型的服务Sentinel(哨兵)。Sentinel次要负责监控、告诉、主动故障转移、配置提供者。简略来说就是,Sentinel能够监督数据节点(master和slave)衰弱状态,并告诉DBA(数据库管理人员),如果master挂了,从泛滥slave中选举一个新的master,并且通知客户端(cli)数据节点的信息。 Cluster:哨兵模式尽管相较于主从模式来说,友善了很多,然而master不好做负载,并且贮存受单机限度,还引入了另外一种类型的服务,有些繁琐。于是乎,Cluster就来了,通常具备 高可用、可扩展性、分布式、容错 等个性。当然,Cluster和哨兵模式没有明确的谁好谁坏,还是要看本人的需要的。个别分布式,应用Cluster好一些。 主从模式在搭建主从模式和Cluster之前,我默认你会装置单机的redis,并且你的环境是Linux(CentOS7),你的Redis版本是5.0.9。如果不会单机redis装置,请戳。 首先将原生的redis.conf复制两份到/usr/local门路下: cp redis.conf /usr/local/redis_master.confcp redis.conf /usr/local/redis_replic.conf而后利用vim批改两个配置文件,批改主要参数如下:redis_master.conf # 主机地址,默认是127.0.0.1,批改成0.0.0.0bind 0.0.0.0# 端口port 16379# 是否开启为守护线程,默认是no,改成yesdaemonize yes# 指定redis过程的PID文件寄存地位 给文件重命名pidfile /var/run/redis_16379.pid# 日志寄存地位 给文件重命名logfile /var/log/redis_16379.log# rdb模式长久化快照dbfilename dump-16379.rdb# 长久化文件寄存地位dir ./redis-workir# redis连贯明码requirepass 123456# 连贯主服务器的明码,这里能够省略masterauth 123456redis_replic.conf # 主机地址,默认是127.0.0.1,批改成0.0.0.0bind 0.0.0.0# 端口port 26379# 是否开启为守护线程,默认是no,改成yesdaemonize yes# 指定redis过程的PID文件寄存地位 给文件重命名pidfile /var/run/redis_26379.pid# 日志寄存地位 给文件重命名logfile /var/log/redis_26379.log# rdb模式长久化快照dbfilename dump-26379.rdb# 长久化文件寄存地位dir ./redis-workir# redis连贯明码requirepass 123456# 连贯主服务器的明码masterauth 123456# 本复制节点的主节点地址replicaof 你服务器外网ip 16379下面留神,在之前的版本replicaof叫做slaveof 。这里,咱们模拟有两台主机,所以主机ip不写127.0.0.1了,写你服务器外网的ip,前面也不便说下网关的问题。而后开启两个服务。 redis-server /usr/local/redis_master.confredis-server /usr/local/redis_replic.conf此时查看两个服务日志,都成长启动了。然而此时master,写数据,slave无奈复制数据,查看日志报错 Error condition on socket for SYNC: No route to host这边须要关上服务器的防火墙,用到iptables,装置请移步我上篇博客(请戳)。 ...

November 22, 2020 · 5 min · jiezi

关于redis:那些年我们用过的RedisLinux下Redis安装与使用

一款由C编写的开源、基于内存、单线程、可长久化的NoSql数据库。环境与版本linux环境为腾讯云单核`CentOS7.2.1511`。redis版本为5.0.9。Redis官网下载地址. 为什么不装置redis6版本?CentOS7,原装的gcc版本为4.8.5。装置redis6须要降级gcc版本,目前最新的gcc版本为gcc10,辣条君尝试装置gcc9版本,发现编译2个多小时都没有完结。网上说,编译时能够应用make -j4,能够开启多过程编译,but辣条君的服务器是单核的,遂放弃降级gcc,乖乖的装置redis5。redis5诞生于2018年底,基本功能蛮弱小了。 装置能够应用wget命令下载redis安装包,或者从官网上下载安装包copy到你的环境中。 # 下载cd /usr/local/wget http://download.redis.io/releases/redis-5.0.9.tar.gz # 解压tar -zxvf redis-5.0.9.tar.gz 编译 cd /redis-5.0.9makemake install PREFIX=/usr/local/redis此时,查看/usr/local/redis/bin门路会发现redis可执行文件。将罕用的可执行文件放到环境变量中。 cd ..cd redis/bin/# 个别都具备超级权限,sudo能够去掉sudo cp redis-cli redis-server redis-sentinel /usr/local/bin此时,你的redis就能够启动应用了,为了便于管理文件,咱们把配置文件放到适合的地位,并批改下配置文件。 cd /usr/local/redis-5.0.9/# 咱们应用的配置文件在 /usr/local/redis.confcp redis.conf /usr/local/cd..# 应用vim 查看并批改redis.confvim redis.conf批改配置文件咱们应用vim批改局部参数,其余默认就好。 # 主机地址,默认是127.0.0.1,批改成0.0.0.0bind 0.0.0.0# 端口 默认就好port 6379# 是否开启为守护线程,默认是no,改成yesdaemonize yes# 指定redis过程的PID文件寄存地位 给文件重命名pidfile /var/run/redis_6379.pid# 日志寄存地位 给文件重命名logfile /var/log/redis_6379.log# rdb模式长久化快照,默认就好dbfilename dump.rdb# 长久化文件寄存地位 默认就好dir ./# redis连贯明码requirepass 123456以上,能够依据正文很好的了解并批改局部配置文件。具体解释下几个参数: bind设置成0.0.0.0,是为了保障本服务器以外的客户端能够拜访本redis服务。 daemonize设置成yes,将redis服务变成守护过程。在该模式下,redis会在后盾运行,并将过程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将始终运行,除非手动kill该过程。daemonize选项设置成no时,以后界面将进入redis的命令行界面,exit强制退出或者敞开连贯工具(putty,xshell等)都会导致redis过程退出。 requirepass :如果你是云服务,这个明码肯定要设置!否则,服务器很容易被某些人拿去当矿机,就是所有服务都给你停掉,只开起挖矿程序,那你真成了打工人了。别问辣条君怎么晓得的。。 启动与应用启动so easy,就一行。 redis-server /usr/local/redis.conf# 查看一下是否启动ps -ef | grep redis# 发现过程阐明OK了root 11890 1 0 Nov04 ? 00:02:39 redis-server 0.0.0.0:6379咱们的应用,分为3种状况:本服务器内应用、其余机器(你的个人电脑)可视化客户端应用、其余机器(你的个人电脑)cli客户端应用。 ...

November 22, 2020 · 1 min · jiezi

关于redis:redis学习-redis-持久化

redis学习 - redis 长久化无论面试和工作,长久化都是重点。 个别状况下,redis占用内存超过20GB以上的时候,必须思考主从多redis实例进行数据同步和备份保障可用性。 rbd保留的文件都是 dump.rdb,都是配置文件当中的快照配置进行生成的。个别业务状况只须要用rdb即可。 aof默认是不开启的,因为aof非常容易产生大文件,尽管官网提供重写然而在文件体积过大的时候还是容易造成阻塞,审慎思考应用 rbd和aof在大数据量别离有各种不同状况的零碎性能影响,具体应用何种解决策略须要依据系统资源以及业务的理论状况决定。 数据设计影响长久化:https://szthanatos.github.io/... 为什么要长久化?重用数据避免系统故障备份重要数据长久化的形式RDB 快照:将某一个时刻的所有数据写入到磁盘AOF(append-only file):将所有的命令写入到此判断。默认状况:RDB,AOF须要手动开启 redis.conf长久化配置阐明在redis.conf文件当中,存在如下的选项: redis.conf当中RDB的相干配置 #是否开启rdb压缩 默认开启rdbcompression yes#代表900秒内有一次写入操作,就记录到rdbsave 900 1# rdb的备份文件名称dbfilename dump.rdb# 示意备份文件寄存地位dir ./redis.conf当中AOF的相干配置 # 是否开启aof,默认是敞开的appendonly no#aof的文件名称appendfilename "appendonly.aof"# no: don't fsync, just let the OS flush the data when it wants. Faster.# always: fsync after every write to the append only log. Slow, Safest.# everysec: fsync only one time every second. Compromise.appendfsync everysec# 在进行rewrite的时候不开启fsync,即不写入缓冲区,间接写入磁盘,这样会造成IO阻塞,然而最为平安,如果为yes示意写入缓冲区,写入的适宜redis宕机会造成数据长久化问题(在linux的操作系统的默认设置下,最多会失落30s的数据)no-appendfsync-on-rewrite no# 上面两个参数要配合应用,代表当redis内容大于64m同时扩容超过100%的时候会执行bgrewrite,进行长久化auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbRDB创立rdb快照的几种形式:客户端向redis发送bgsave的命令(留神windows不反对bgsave),此时reids调用 fork 创立子过程,父过程持续解决,子过程将快照写入磁盘,父过程持续解决申请。客户端发送save命令创立快照。留神这种形式会阻塞整个父过程。很少应用,非凡状况才应用。redis通过shutdown命令敞开服务器申请的时候,此时redis会停下所有工作执行一次save,阻塞所有客户端不再执行任何命令并且进行磁盘写入,写入实现敞开服务器。redis集群的时候,会发送sync 命令进行一次复制操作,如果主服务器没有执行或者刚刚执行完bgsave,则会进行bgsave。执行flushall 命令RDB快照的一些留神点:只应用rdb的时候,如果创立快照的时候redis解体,redis会留存上一次备份快照,然而具体失落多少数据由备份工夫查看只实用一些能够容忍肯定数据失落的零碎,否则须要思考aof长久化在大数据量的场景下,特地是内存达到20GB以上的适宜,一次同步大概要4-6秒 ...

November 21, 2020 · 2 min · jiezi

关于redis:vscode-查看Redis源码

简介最近在学习Redis源码,次要是目前负责华为产品FusionInsight HD中Redis组件的相干事务,不得不学习Redis源码。本文次要讲述的是怎么通过vscode查看Redis的源码(Linux平台上面). 配置在我的项目上面减少文件夹 .vscode,并且新建文件:launch.json 、tasks.json、 c_cpp_properties.json,并且在文件中增加上面内容: launch.json: { "version": "0.2.0", "configurations": [ { "name": "build", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/src/redis-server", "args": [ "redis.conf" ], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "preLaunchTask": "shell" } ]}tasks.json: { "version": "2.0.0", "tasks": [ { "label": "shell", "type": "shell", "command": "/usr/bin/make" } ]}c_cpp_properties.json { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**" ], "defines": [], "compilerPath": "/usr/bin/clang", "cStandard": "c11", "cppStandard": "c++14", "intelliSenseMode": "clang-x64" } ], "version": 4}运行应用快捷键F5进行编译调试。 ...

November 21, 2020 · 1 min · jiezi

关于redis:关于Redis-三种持久化你需要了解的事儿

Redis 长久化前言Rdis的读写都是在内存中进行,所以redis的性能很高。长久化能够无效地防止因过程退出而造成数据失落问题,下次重启的时候利用之前长久化文件能够实现数据恢复。 长久化的几种形式Redis 长久化领有以下三种形式: 快照形式(RDB, Redis DataBase)RDB长久化是把以后过程数据生成快照保留到硬盘的过程,触发RDB长久化过程分为手动触发和主动触发文件追加形式(AOF, Append Only File)记录所有的操作命令,并以文本的模式追加到文件中;混合长久化形式,Redis 4.0 之后新增的形式,混合长久化是联合了 RDB 和 AOF 的长处,在写入的时候,先把以后的数据以 RDB 的模式写入文件的结尾,再将后续的操作命令以 AOF 的格局存入文件,这样既能保障 Redis 重启时的速度,又能减低数据失落的危险。以上三种长久化计划,每一种都有特定的应用场景,具体的咱们能够依据本人的需要自行抉择。 RDB长久化RDB(Redis DataBase)是将某一个时刻的内存快照(Snapshot),以二进制的形式写入磁盘的过程。 RDB的长久化形式有两种: 一种是手动触发,一种是主动触发 手动触发手动触发Redis提供了两个命令 :save 和 bgsave 。 save 命令save 手动触发会阻塞主线程 在客户端执行save命令时候,就会触发长久化,但也会使得Redis主线程阻塞,必须等到RDB长久化实现之后,才会相应客户端的命令,线上环境不倡议应用。 下图演示应用save命令 启动Redis (默认配置是rdb长久化形式),rdb文件工夫。 而后应用save长久化数据 而后查看长久化后rdb文件的工夫阐明手动长久化文件胜利 bgsave 命令bgsave不会阻塞主线程 应用bgsave命令时候,Redis过程执行fork操作创立子过程,RDB长久化过程由子 过程负责,实现后主动完结。阻塞只产生在fork阶段,个别工夫很短,根本不会产生阻塞,与save命令相比显然bgsave更适宜咱们长久化数据。 下图示意开始主动长久化数据 主动触发如何主动触发 RDB 长久化? 在redis.conf文件中有这么一个配置 什么意思呢? save m n save m n 示意m秒内数据集存在n次批改 时,主动触发bgsave命令。 save 900 1 则表明在 900 秒内,至多有一个键产生扭转,就会触发 RDB 长久化。save 300 10 则表明在 300 秒内,至多有10个键产生扭转,就会触发 RDB 长久化。save 60 10000 则表明在 60 秒内,至多有10000个键产生扭转,就会触发 RDB 长久化。满足以上任意一个条件,Redis 就会主动触发bgsvae命令进行长久化工作。 ...

November 21, 2020 · 2 min · jiezi

关于redis:Redis-持久化快速上手

什么是长久化?Redis 所有数据都是存储在内存中的,对于数据的更新将异步的保留在磁盘中,当Redis实例重启时,即可利用之前长久化的文件实现数据恢复。 支流数据库的长久化形式: 快照 Mysql dumpRedis rdb日志 Mysql binlogRedis aofRDB什么是RDB?Redis 通过一条命令或者某种形式创立 rdb 文件,该文件是二进制格局,存储在硬盘中。 当须要对Redis 进行复原时,就能够去加载该文件。 数据恢复的水平,取决于 rdb文件(快照)产生的时刻。 三种触发机制Redis 生成 rdb 文件有三种形式,别离是: savebgsave主动策略savesave 命令有如下特点: 同步阻塞文件策略:如果存在旧的rdb 文件,则会替换成新的复杂度:O(N)bgsavebgsave 命令有如下特点: 异步非阻塞(简直不会阻塞客户端)文件策略和复杂度同上。save 还是 bgsave?命令savebgsaveIO类型同步异步是否阻塞是否(阻塞产生在fork()复杂度O(n)O(n)长处不会耗费额定内存不阻塞客户端毛病阻塞客户端须要fork,耗费内存在数据量不大的状况下,其实应用save 还是bgsave 并没有什么差别。 主动策略主动生成策略是依据某个规定来决定是否生成 rdb 文件,这个过程也是一个bgsave 的过程。 默认策略: secondschanges9001300106010000上述配置的意思是:如果在60s 中做了10000 次扭转或者在 300s 中做了 10次 扭转,或者在900s 中做了 1 次扭转,则均会触发bgsave。 配置#save 900 1#save 300 10 #save 60 10000dbfilename dump-${port}.rdb // rdb 文件名称dir /big_disk_path // 工作目录stop-writes-on-bgsave-error yes // 如果产生谬误,进行写入rdbcompression yes // 采纳压缩格局 rdbchecksum yes // 对rdb 文件进行测验触发机制Redis 当达到以下触发机制时,也会主动创立rdb 文件。 ...

November 21, 2020 · 1 min · jiezi

关于redis:Redis-从入门到精通基础

一、前言大家好,我是深度Linux,本系列专栏是对 Redis 的入门以及进阶应用,心愿对大家有所帮忙。 二、根底(1)介绍 首先来看下redis 官网,如果感觉看着吃力,也有国人翻译的中文版本redis 中文网站。上面来看一下网站对Redis的介绍。 Redis 是一个开源(BSD 许可)的,内存中的数据结构存储系统,它能够用作数据库、缓存和消息中间件。 它反对多种类型的数据结构,如字符串(strings), 散列(hashes), 列表(lists), 汇合(sets), 有序汇合(sorted sets)范畴查问, bitmaps, hyperloglogs 和 天文空间(geospatial) 索引半径查问。 Redis 内置了复制(replication),LUA 脚本(Lua scripting), LRU 驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘长久化(persistence), 并通过 Redis哨兵(Sentinel)和主动 分区(Cluster)提供高可用性(high availability)。如果看了还感觉莫名其妙,没关系。简略来说Redis是一种基于键值(Key-Value)的高性能内存数据库。它提供了一些有用且不便的数据结构,比方Value能够string、hash、list、set、zset,因为这种构造的存在,咱们平时的开发中就能够灵便的利用这些构造优化咱们的技术实现。同时Redis还提供了键过期,公布订阅,事务,流水线等其它附加性能。如果看到这里你还没明确,没关系,接下来我将一点一点揭开它神秘的面纱。让你真正做到从入门到夺门而出。(2)个性如果有人问你,你用过Redis,那它有什么个性呢,上面的答案请务必记住(当然了,忘性不好的譬如我记住几条要害的也可)。来看一下答案: 速度快,读写性能10W/s,当然了和机器配置也有关系为什么快呢?内存操作,C语言实现,离操作系统API更近;单线程架构(务必不要记错),防止了多线程竞争带来的损耗。IO多路复用,协定简略。反对长久化,尽管是交互时是内存操作,但提供数据落盘机制,避免断电产生的数据失落问题。反对主从复制:多正本 Master-Slave 节点反对高可用 HA:哨兵(sentinel)机制实现高可用,保障节点故障主动发现和故障转移反对多客户端语言:Java、Python、C++等。(3)应用场景那什么时候能够思考应用呢?什么时候能够用而不是故意炫技呢?来看一下目前常见的应用状况: 缓存:数据库之前加缓存,升高数据库读写压力排行榜:依照热度排名、依照公布工夫排名计数器:播放数、浏览数社交网络:赞、踩、粉丝、下拉刷新音讯队列:公布订阅(4)装置Redis反对Windows和Linux,如果只是本人玩玩,能够间接应用Windows版本,十分的简略和疾速就能启动。这里就不给出Windows环境下的安装包了,网上一搜到处都是。上面次要阐明下Linux环境下的装置与根本配置(当然了,只是以启动服务客户端能够连贯为目标的简略配置)以centos7举例:1、依赖查看 yum install cpp -yyum install binutils -y yum install glibc-kernheaders -y yum install glibc-common -y yum install glibc-devel -y yum install gcc -y yum install make -y 2、下载编译安装包 ...

November 17, 2020 · 2 min · jiezi

关于redis:Redis我这21个灵魂拷问你拿什么挡

前言欢送各位进群973961276一起聊聊技术吹吹牛,每周都会有几次抽奖送专业书籍的流动,奖品虽不甚值钱,但也可搏个彩头 1.什么是redis?Redis 是一个基于内存的高性能key-value数据库。 2.Reids的特点Redis实质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库通通加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保留。因为是纯内存操作,Redis的性能十分杰出,每秒能够解决超过 10万次读写操作,是已知性能最快的Key-Value DB。 Redis的杰出之处不仅仅是性能,Redis最大的魅力是反对保留多种数据结构,此外单个value的最大限度是1GB,不像 memcached只能保留1MB的数据,因而Redis能够用来实现很多有用的性能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能音讯队列服务,用他的Set能够做高性能的tag零碎等等。另外Redis也能够对存入的Key-Value设置expire工夫,因而也能够被当作一 个性能加强版的memcached来用。 Redis的次要毛病是数据库容量受到物理内存的限度,不能用作海量数据的高性能读写,因而Redis适宜的场景次要局限在较小数据量的高性能操作和运算上。 零根底和大三大四的敌人看这里>>c/c++ 企业级我的项目实战 曾经工作了想持续自我晋升跳槽涨薪的工程师看这里>>c/c++ linux服务器高级架构师学习 3.应用redis有哪些益处?1.速度快,因为数据存在内存中,相似于HashMap,HashMap的劣势就是查找和操作的工夫复杂度都是O(1) 2.反对丰盛数据类型,反对string,list,set,sorted set,hash 1)String 常用命令:set/get/decr/incr/mget等; 利用场景:String是最罕用的一种数据类型,一般的key/value存储都能够归为此类; 实现形式:String在redis外部存储默认就是一个字符串,被redisObject所援用,当遇到incr、decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。 2)Hash 常用命令:hget/hset/hgetall等 利用场景:咱们要存储一个用户信息对象数据,其中包含用户ID、用户姓名、年龄和生日,通过用户ID咱们心愿获取该用户的姓名或者年龄或者生日; 实现形式:Redis的Hash理论是外部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。Key是用户ID, value是一个Map。这个Map的key是成员的属性名,value是属性值。这样对数据的批改和存取都能够间接通过其外部Map的Key(Redis里称外部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就能够操作对应属性数据。 以后HashMap的实现有两种形式:当HashMap的成员比拟少时Redis为了节俭内存会采纳相似一维数组的形式来紧凑存储,而不会采纳真正的HashMap构造,这时对应的value的redisObject的encoding为zipmap,当成员数量增大时会主动转成真正的HashMap,此时encoding为ht。 3)List 常用命令:lpush/rpush/lpop/rpop/lrange等; 利用场景:Redis list的利用场景十分多,也是Redis最重要的数据结构之一,比方twitter的关注列表,粉丝列表等都能够用Redis的list构造来实现; 实现形式:Redis list的实现为一个双向链表,即能够反对反向查找和遍历,更不便操作,不过带来了局部额定的内存开销,Redis外部的很多实现,包含发送缓冲队列等也都是用的这个数据结构。 4)Set 常用命令:sadd/spop/smembers/sunion等; 利用场景:Redis set对外提供的性能与list相似是一个列表的性能,非凡之处在于set是能够主动排重的,当你须要存储一个列表数据,又不心愿呈现反复数据时,set是一个很好的抉择,并且set提供了判断某个成员是否在一个set汇合内的重要接口,这个也是list所不能提供的; 实现形式:set 的外部实现是一个 value永远为null的HashMap,理论就是通过计算hash的形式来疾速排重的,这也是set能提供判断一个成员是否在汇合内的起因。 5)Sorted Set 常用命令:zadd/zrange/zrem/zcard等; 利用场景:Redis sorted set的应用场景与set相似,区别是set不是主动有序的,而sorted set能够通过用户额定提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即主动排序。当你须要一个有序的并且不反复的汇合列表,那么能够抉择sorted set数据结构,比方twitter 的public timeline能够以发表工夫作为score来存储,这样获取时就是主动按工夫排好序的。 实现形式:Redis sorted set的外部应用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里寄存的是所有的成员,排序根据是HashMap里存的score,应用跳跃表的构造能够取得比拟高的查找效率,并且在实现上比较简单。 3.反对事务,操作都是原子性,所谓的原子性就是对数据的更改要么全副执行,要么全副不执行 4.丰盛的个性:可用于缓存,音讯,按key设置过期工夫,过期后将会主动删除 4.redis相比memcached有哪些劣势?memcached所有的值均是简略的字符串,redis作为其替代者,反对更为丰盛的数据类型redis的速度比memcached快很多 (3) redis能够长久化其数据5.Memcache与Redis的区别都有哪些?存储形式 Memecache把数据全副存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部份存在硬盘上,这样能保证数据的持久性。数据反对类型 Memcache对数据类型反对绝对简略。Redis有简单的数据类型。应用底层模型不同 它们之间底层实现形式 以及与客户端之间通信的利用协定不一样。Redis间接本人构建了VM 机制 ,因为个别的零碎调用零碎函数的话,会节约肯定的工夫去挪动和申请。6.redis实用于的场景?Redis最适宜所有数据in-momory的场景,如: ...

November 17, 2020 · 2 min · jiezi

关于redis:如何保证核心链路稳定性的流控和熔断机制

仅从设计优化、服务拆分、主动扩容等方面进行优化,有时候并不能齐全解决问题。比方,有时流量增长过快,扩容流程还来不及实现,服务器可能就曾经抗不住了 既然突发流量咱们没法预测,业务上也不可能不依赖任何内部服务和资源,那么有什么方法能尽量避免,或者升高呈现这些问题时对外围业务的影响呢? 流量管制01.流控罕用的算法目前业内罕用的流控办法有两种:漏桶算法和令牌桶算法 漏桶算法“漏桶算法”的次要目标是控制数据注入到网络的速率,平滑网络上的突发流量。“漏桶算法”在实现上文如其名:它模仿的是一个漏水的桶,所有内部的水都先放进这个水桶,而这个桶以匀速往外平均漏水,如果水桶满了,内部的水就不能再往桶里倒了。这里你能够把这些内部的水设想成原始的申请,桶里漏出的水就是被算法平滑过后的申请。从这里也能够看进去,漏桶算法能够比拟好地管制流量的访问速度。 令牌算法令牌桶算法是流控中另一种罕用算法,管制的是一个工夫窗口内通过的数据量。令牌桶算法大略实现是这样的: 每 1/r 秒往桶里放入一个令牌,r 是用户配置的均匀发送速率(也就是每秒会有 r 个令牌放入)。桶里最多能够放入 b 个令牌,如果桶满了,新放入的令牌会被抛弃。如果来了 n 个申请,会从桶里消耗掉 n 个令牌。如果桶里可用令牌数小于 n,那么这 n 个申请会被抛弃掉或者期待新的令牌放入。 算法按肯定速度平均往桶里放入令牌,原始申请进入后,依据申请量从令牌桶里取出须要的令牌数,如果令牌数不够,会间接摈弃掉超限的申请或者进行期待,能胜利获取到令牌的申请才会进入到后端服务器。 与漏桶算法“准确管制速率”不太一样的是,因为令牌桶的桶自身具备肯定的容量,能够容许一次把桶里的令牌全都取出,因而,令牌桶算法在限度申请的均匀速率的同时,还容许肯定水平的突发流量。 算法按肯定速度平均往桶里放入令牌,原始申请进入后,依据申请量从令牌桶里取出需 02.全局流控在分布式服务的场景下,很多时候的瓶颈点在于全局的资源或者依赖,这种状况就须要分布式的全局流控来对整体业务进行爱护。 业界比拟通用的全局流控计划,个别是通过地方式的资源(如:Redis、Nginx)配合脚本来实现全局的计数器,或者实现更为简单的漏桶算法和令牌桶算法,比方能够通过 Redis 的 INCR 命令配合 Lua 实现一个限度 QPS(每秒查问量)的流控组件。 一个须要留神的细节是:在每次创立完对应的限流 Key 后,你须要设置一个过期的工夫。整个操作是原子化的,这样能防止分布式操作时设置过期工夫失败,导致限流的 Key 始终无奈重置,从而使限流性能不可用。此外,在实现全局流控时还有两个问题须要留神:一个是流控的粒度问题,另一个是流控依赖资源存在瓶颈的问题。上面咱们别离来看一下,在实现全局流控时是如何解决这两个问题的。 03.细粒度管制首先是针对流控的粒度问题。举个例子:在限度 QPS 的时候,流控粒度太粗,没有把 QPS 平均摊派到每个毫秒里,而且边界解决时不够平滑,比方上一秒的最初一个毫秒和下一秒的第一个毫秒都呈现了最大流量,就会导致两个毫秒内的 QPS 翻倍。 一个简略的解决形式是把一秒分成若干个 N 毫秒的桶,通过滑动窗口的形式,将流控粒度细化到 N 毫秒,并且每次都是基于滑动窗口来统计 QPS,这样也能防止边界解决时不平滑的问题。 主动熔断机制雪崩效应在多依赖服务中往往会导致一个服务出问题,从而拖慢整个零碎的状况。 为了便于管理和隔离,咱们常常会对服务进行解耦,独立拆合成耦到不同的微服务中,微服务间通过 RPC 来进行调用和依赖: 手动通过开关来进行依赖的降级主动熔断机制次要是通过继续收集被依赖服务或者资源的拜访数据和性能指标,当性能呈现肯定水平的好转或者失败量达到某个阈值时,会主动触发熔断,让以后依赖疾速失败(Fail-fast),并降级到其余备用依赖,或者暂存到其余中央便于后续重试复原。在熔断过程中,再通过不停探测被依赖服务或者资源是否复原,来判断是否主动敞开熔断,复原业务。往期举荐Redis删除数据后,为什么内存占用率还是很高?Redis三种长久化形式音讯模型:主题和队列有什么区别?Hash算法原理解析MySQL中乐观锁和乐观锁到底是什么?

November 16, 2020 · 1 min · jiezi

关于redis:ddd

errerr

November 16, 2020 · 1 min · jiezi

关于redis:Redis哨兵3

1.Redis长久化策略1.1 什么是长久化:阐明:Redis运行环境在内存中,如果服务器敞开则内存数据讲话失落; 需要: 如何放弃内存数据解决方案:能够定期将内存数据长久化到磁盘中 长久化策略规定:当redis失常运行时,定期的将数据保留到磁盘中,当redis服务器重启时,则依据配置文件中指定的长久化形式,事项数据的回复(读取数据之后回复数据) 1.2 RDB模式:1.2.1 RDB模式 是Redis默认的策略;1.2.2 RDB模式 可能定期长久化(工夫距离),弊病_可能导致数据的失落;1.2.3 RDB模式 记录的是内存数据的快照,长久化效率较高,快照只保留最新记录;1.2.4 RDB模式命令: save 命令:将内存数据长久化到磁盘中 ----主动式操作毛病___ 会造成线程的阻塞 bgsave 命令:将内存数据采纳后盾运行的形式,长久化到磁盘中默认的长久化的机制:a. save 900 1 如果在900秒内执行了1次更新操作,则长久化一次b. save 300 10 如果在300秒内执行了10次更新操作,则长久化一次c. save 60 10000 如果在60秒内执行了10000次更新操作,则长久化一 1.3 AOF模式:1.3.1 AOF模式特点: AOF模式默认条件下是敞开的,须要手动开启;AOF模式记录的是用户的操作过程,所以能够实现实时长久化操作;AOF模式因为记录的是实时的操作过程,所以长久化文件较大,须要定期维护;1.3.2 启动AOF模式: (redis 重启 redis-cli sutd缩写)阐明: 如果开启AOF模式 则一AOF模式为准如何开启:进入 vim redis.conf 批改appendonly no 批改为yes1.4 对于长久化操作总结:当内存数据容许大量失落是,应用RDB模式(快);当内存数据不容许数据失落是,采纳AOF(定期须要保护);个别在工作中采纳AOF+RDB模式独特作用,保证数据的有效性2. Redis内存策略2.1为什么须要内存优化阐明:因为redis在内存中保留数据,如果始终存储,则内存必然溢出所以须要定期维护内存数据的大小 保护策略: 删除旧的不必的数据,保留新的罕用的数据;2.2 LRU算法:阐明: LRU最近起码应用,是一种罕用的页面置换算法,抉择最近最久未应用的数据予以淘汰;计算维度 工夫T注意事项: 是迄今为止内存中最好用的数据置换算法;2.3 LFU算法阐明:最不常常应用数据置换算法 ,要求在数据置换是置换援用计数最下的数据,因为常常应用的数据应该有一个较大的援用次数;计算维度: 应用次数2.4 随机算法2.5 TTL算法阐明 依据存活工夫,将马上要超时的数据提前删除;2.6 配置内存优化策略valatile-lru 在设定了超时工夫的数据,采纳lru算法allkeys-lru 在所有的数据中采纳lru算法volatile-lfu 在设定了超时工夫的诗句中采纳lfu算法allkeys-lfu 所有数据采纳lfu算法volatile-random 设置超时工夫数据的随机算法allkeys-random 所有数据随机volatile-ttl 将设定了超时工夫的数据 提前删除noeviction 如果设置了noeviction 则不删除数据 间接保留返回3. 对于缓存的面试问题问题出发点: ...

November 16, 2020 · 1 min · jiezi

关于redis:Redis集群

实现Redis集群为什么须要搭建集群rediis分片特点:1.能够实现Redis内存数据的扩容。2.redis分片自身没有高可用成果,如果宕机将间接影响用户的应用。redis哨兵特点:1.redis哨兵能够实现redis节点的高可用,然而哨兵自身没有实现高可用机制2.redis哨兵有主从的构造,实现了内存数据的备份,然而没有实现内存扩容的成果。降级:须要redis内容扩大,同时须要redis高可用性,所以应该应用Redis集群。 Redis集群Hash槽的简述Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定搁置哪个槽.集群的每个节点负责一部分hash槽。这种构造很容易增加或者删除节点,并且无论是增加删除或者批改某一个节点,都不会造成集群不可用的状态。应用哈希槽的益处就在于能够不便的增加或移除节点。当须要减少节点时,只须要把其余节点的某些哈希槽挪到新节点就能够了;当须要移除节点时,只须要把移除节点上的哈希槽挪到其余节点就行了;在这一点上,咱们当前新增或移除节点的时候不必先停掉所有的 redis 服务。 对于Redis集群搭建问题1.敞开所有的redis服务器 sh stop.sh2.删除多余的文件 3.重启redis服务器,执行挂载命令 redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7000 192.168.126.129:7001 192.168.126.129:7002 192.168.126.129:7003 192.168.126.129:7004 192.168.126.129:7005Redis入门案例@Test public void testCluster(){ Set<HostAndPort> nodes = new HashSet<>(); nodes.add(new HostAndPort("192.168.126.129", 7000)); nodes.add(new HostAndPort("192.168.126.129", 7001)); nodes.add(new HostAndPort("192.168.126.129", 7002)); nodes.add(new HostAndPort("192.168.126.129", 7003)); nodes.add(new HostAndPort("192.168.126.129", 7004)); nodes.add(new HostAndPort("192.168.126.129", 7005)); JedisCluster jedisCluster = new JedisCluster(nodes); jedisCluster.set("cluster", "集群的测试!!!!"); System.out.println(jedisCluster.get("cluster")); }对于Redis中的脑裂景象阐明:当集群进行选举时,如果间断3次都呈现了平票的后果,则可能呈现脑裂的景象。呈现脑裂景象的概率为1/8=12.5%预防:减少主节点的数量能够无效的升高脑裂景象的产生。问题1.Redis集群中最多能存储16384个数据?谬误的,分区只负责数据的划分,数据的存储由内存决定。问题2:Redis集群中最多由多少台主机?~~~~16384台主机。一台主机占用一个槽道。 SpringBoot整合Redis集群编辑pro配置文件# 配置redis单台服务器redis.host=192.168.126.129redis.port=6379# 配置redis分片机制redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381# 配置哨兵节点redis.sentinel=192.168.126.129:26379# 配置redis集群redis.clusters=192.168.126.129:7000,192.168.126.129:7001,192.168.126.129:7002,192.168.126.129:7003,192.168.126.129:7004,192.168.126.129:7005编辑RedisConfig配置类@Configuration@PropertySource("classpath:/properties/redis.properties")public class JedisConfig { @Value("${redis.clusters}") private String clusters; @Bean public JedisCluster jedisCluster(){ Set<HostAndPort> nodes = new HashSet<>(); String[] nodesArray = clusters.split(","); for (String node : nodesArray){ String host = node.split(":")[0]; int port = Integer.parseInt(node.split(":")[1]); HostAndPort hostAndPort = new HostAndPort(host,port); nodes.add(hostAndPort); } return new JedisCluster(nodes); } }编辑CacheAOP ...

November 15, 2020 · 1 min · jiezi

关于redis:redis的五种数据结构和应用场景如微博微信点赞共同关注加购物车

Redis五种数据结构如下: 1.String 字符串类型是redis中最根本的数据类型,一个key对应一个value。 String类型是二进制平安的,意思是 redis 的 string 能够蕴含任何数据。如数字,字符串,jpg图片或者序列化的对象。 2.Hash (哈希)是一个Mapmap,指值自身又是一种键值对构造,如 value={{field1,value1},......fieldN,valueN}} 3.链表 (List)List 说白了就是链表(redis 应用双端链表实现的 List),是有序的,value能够反复,能够通过下标取出对应的value值,左右两边都能进行插入和删除数据。 4.Set 汇合汇合类型也是用来保留多个字符串的元素,但和列表不同的是汇合中 1. 不容许有反复的元素,2.汇合中的元素是无序的,不能通过索引下标获取元素,3.反对汇合间的操作,能够取多个汇合取交加、并集、差集。 5.zset 有序汇合有序汇合和汇合有着必然的分割,保留了汇合不能有反复成员的个性,区别是,有序汇合中的元素是能够排序的,它给每个元素设置一个分数,作为排序的根据。 利用场景String利用场景 1. 单值缓存Set Key Value Get Key 2. 对象缓存1.Set user:1 value (json格局数据) 2.MSet user:1:name guajia use:1:balance 1888 MGet user1:name user:1:balance 3. 分布式锁:3.1 分布式使用场景一【下单减库存】 如图标红的局部,如果是单体架构 咱们个别是这样来实现减库存操作的 然而在高并发的互联网公司这样做,就会造成“超卖”的景象。所以就须要redis来实现分布式锁 如上图标记SETNX命令 它只会存入一个不存在的键值对,如果不会扭转原来的key所存入的值,返回后果为0 SETNX product:10001 true //返回1代表获取锁胜利 返回0代表获取锁失败 ---》 执行业务操作【这样如果setnx 命令返回0 间接扔给前端后端服务正忙 请稍后重试】DEL product:10001 //执行完业务用它来开释锁 SET product:10001 true ex 10 nx //避免程序意外终止而导致死锁 ...

November 15, 2020 · 2 min · jiezi

关于redis:Codis源码分析之环境篇

一、Codis介绍 Codis是豌豆荚开源的Redis集群计划,github地址: https://github.com/CodisLabs/... 以下是官网介绍: Codis 是一个分布式 Redis 解决方案, 对于下层的利用来说, 连贯到 Codis Proxy 和连贯原生的 Redis Server 没有显著区别 (不反对的命令列表), 下层利用能够像应用单机的 Redis 一样应用, Codis 底层会解决申请的转发, 不停机的数据迁徙等工作, 所有后边的所有事件, 对于后面的客户端来说是通明的, 能够简略地认为后边连贯的是一个内存无限大的 Redis 服务。https://github.com/CodisLabs/... Codis次要解决的是redis的扩大和运维问题,因为redis官网以前没有集群计划,自从3.0才有,并且刚开始做的比拟弱,特地是运维这块不是很敌对,很多都是命令行操作的。咱们能够认为Codis是一个能够反对容量能够有限扩充的Redis集群就行。 二、Codis装置及配置 1、整体架构 Codis是由golang写的,因而须要先装置go语言,官网给的文档曾经很具体了,这里不详述。 咱们看下Codis的整体架构,基于3.2: 2、相干概念 Codis Server:能够了解为原生的Redis,在整个集群中充当存储用,即最终数据是存在Redis中的,不过Codis在下面改了些货色,加了些命令,便于集群迁徙和分片; Codis Proxy:客户端连贯的 Redis 代理服务, 实现了 Redis 协定。即Proxy只是一个代理,把命令做解析,而后依据路由规定转到不同的Codis Server中,Proxy是无状态的,能够有限扩容,Proxy信息保留在Zookeeper等Storage(前面再介绍)中,客户端须要本人刷新最新的Proxy列表。 Codis Dashboard:这个是Codis的外围,对集群的绝大部分批改都是它来实现的。官网的介绍如下:集群管理工具,反对 codis-proxy、codis-server 的增加、删除,以及据迁徙等操作;说的比拟抽象,上面咱们会通过代码来阐明其作用。 Codis FE:集群治理界面,能够了解为UI。 Codis Admin:集群治理的命令行工具,可用于管制 codis-proxy、codis-dashboard 状态以及拜访内部存储。为什么有了Dashboard,还要Codis Admin,这个工具的次要定位是通过命令行的形式操作,其实前面的逻辑是一样的,即Codis Admin和Codis Fe是两种不同的界面,最初的逻辑是一样的。 Storage:次要存储元数据,如集群有多少个 Proxy,以后的分片是怎么样的。目前有 Zookeeper、Etcd、Fs等形式的实现。 3、集群启动 整个集群的启动形式官网也有阐明,大体程序如下: 1)、启动codis-dashboard/admin/codis-dashboard-admin.sh start最终启动的是codis-dashboard这个二进制文件: ./bin/codis-dashboard --ncpu=4 --config=dashboard.toml --log=dashboard.log --log-level=WARN次要的参数是--config,即配置文件,外围几个配置如下: ...

November 14, 2020 · 3 min · jiezi

关于redis:SpringBoot整合Redis

1.Redis命令1.1 入门案例操作 2 SpringBoot整合Redis2.1 编辑pro配置文件因为redis的IP地址和端口都是动态变化的,所以通过配置文件标识数据. 因为redis是公共局部,所以写到common中 2.2 编辑配置类 3 对象与JSON串转化3.1 对象转化JSON入门案例 3.2 编辑ObjectMapper工具API 4 实现商品分类缓存实现4.1 编辑ItemCatController阐明: 切换业务调用办法,执行缓存调用 4.2 编辑ItemCatService 5. AOP实现Redis缓存5.1 现有代码存在的问题1.如果间接将缓存业务,写到业务层中,如果未来的缓存代码发生变化,则代码耦合高,必然重写编辑代码.2.如果其余的业务也须要缓存,则代码的反复率高,开发效率低.解决方案: 采纳AOP形式实现缓存. 5.2 AOP在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译形式和运行期间动静代理实现程序性能的对立保护的一种技术。AOP是OOP的连续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP能够对业务逻辑的各个局部进行隔离,从而使得业务逻辑各局部之间的耦合度升高,进步程序的可重用性,同时进步了开发的效率。 5.3 AOP实现步骤公式: AOP(切面) = 告诉办法(5种) + 切入点表达式(4种) 5.3.1 告诉温习1.before告诉 在执行指标办法之前执行2.afterReturning告诉 在指标办法执行之后执行3.afterThrowing告诉 在指标办法执行之后报错时执行4.after告诉 无论什么时候程序执行实现都要执行的告诉 上述的4大告诉类型,不能控制目标办法是否执行.个别用来记录程序的执行的状态.个别利用与监控的操作. 5.around告诉(性能最为弱小的) 在指标办法执行前后执行.因为盘绕告诉能够控制目标办法是否执行.管制程序的执行的轨迹. 5.3.2 切入点表达式1.bean(“bean的ID”) 粒度: 粗粒度 按bean匹配 以后bean中的办法都会执行告诉.2.within(“包名.类名”) 粒度: 粗粒度 能够匹配多个类3.execution(“返回值类型 包名.类名.办法名(参数列表)”) 粒度: 细粒度 办法参数级别4.@annotation(“包名.类名”) 粒度:细粒度 依照注解匹配 5.3.3 AOP入门案例 5.4 AOP实现Redis缓存5.4.1 业务实现策略1).须要自定义注解CacheFind2).设定注解的参数 key的前缀,数据的超时工夫.3).在办法中标识注解.4).利用AOP 拦挡指定的注解.5).应该应用Around告诉实现缓存业务. 5.4.2 编辑自定义注解 ...

November 14, 2020 · 1 min · jiezi

关于redis:redis-分片

1 redis 部署搭建的端口:6379/6380/6381在redis/ 创立一个目录 shards进入shards 目录 : /port 批改port在当前目录 开启redis 测试 配置redis.properties common.config com.jt.aopCacheAOP

November 13, 2020 · 1 min · jiezi

关于redis:Redis哨兵机制

对于redis分片阐明长处:实现内存数据的扩容。毛病:如果redis分片中有一个节点呈现了问题,则整个redis分片机制用户拜访必然会呈现问题,间接影响用户的应用。解决方案:实现redis的高可用。 配置redis主从构造策略划分:1主2从 6379主 6380/6381从1.将分片的目录复制 改名为sentinel2.重启redis服务器3.查看redis节点的主从状态4.实现主从挂载5.查看主机状态 哨兵的工作原理原理阐明:1.配置redis主从的构造。2.哨兵服务启动时,会监控以后的主机,同时获取主机的详情信息(主从的构造)。3.当哨兵刘勇心跳检测机制(PING-PANG)间断3次都没有收到主机的反馈信息则判定主机宕机。4.当哨兵发现主机宕机后,则开启选举机制,在以后的从机中筛选一台Redis当做主机。5.将其余的redis节点设置为新主机的从。 编辑哨兵配置文件1.复制配置文件cp sentinel.conf sentinel/2.批改保护模式3.开启后盾运行4.设定哨兵的监控其中的1示意投票失效的票数,以后只有一个哨兵所以写15.批改宕机工夫6.选举失败的工夫阐明:如果选举超过指定的工夫没有完结,则从新选举7.启动哨兵服务 Redis哨兵高可用实现测试步骤:1.查看主机的状态2.将redis主服务器宕机期待10秒,之后查看从机是否入选新的主机。3.重启6379服务器,查看是否成为了新主机的从 哨兵入门案例/** * 测试Redis哨兵 */ @Test public void testSentinel(){ Set<String> set = new HashSet<>(); //1.传递哨兵的配置信息 set.add("192.168.126.129:26379"); JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster",set); Jedis jedis = sentinelPool.getResource(); jedis.set("aa","哨兵测试"); System.out.println(jedis.get("aa")); }SpringBoot整合Redis哨兵编辑pro配置文件# 配置redis单台服务器redis.host=192.168.126.129redis.port=6379# 配置redis分片机制redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381# 配置哨兵节点redis.sentinel=192.168.126.129:26379编辑redis配置类@Configuration@PropertySource("classpath:/properties/redis.properties")public class JedisConfig { @Value("${redis.sentinel}") private String sentinel; //临时只有单台 @Bean public JedisSentinelPool jedisSentinelPool(){ Set<String> sentinels = new HashSet<>(); sentinels.add(sentinel); return new JedisSentinelPool("mymaster",sentinels); } }批改CacheAOP中的注入项package com.jt.aop;import com.jt.anno.CacheFind;import com.jt.config.JedisConfig;import com.jt.util.ObjectMapperUtil;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisSentinelPool;import redis.clients.jedis.ShardedJedis;import java.lang.reflect.Method;import java.util.Arrays;@Aspect //我是一个AOP切面类@Component //将类交给spring容器治理public class CacheAOP { @Autowired //private Jedis jedis; //单台redis //private ShardedJedis jedis; //分片机制 private JedisSentinelPool jedisSentinelPool; /** * 切面 = 切入点 + 告诉办法 * 注解相干 + 盘绕告诉 控制目标办法是否执行 * * 难点: * 1.如何获取注解对象 * 2.动静生成key prekey + 用户参数数组 * 3.如何获取办法的返回值类型 */ @Around("@annotation(cacheFind)") //参数传递变量的传递 //@Around("@annotation(com.jt.anno.CacheFind)") public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind){ //从池中获取jedis对象 Jedis jedis = jedisSentinelPool.getResource(); Object result = null; try { //1.拼接redis存储数据的key Object[] args = joinPoint.getArgs(); String key = cacheFind.preKey() +"::" + Arrays.toString(args); //2. 查问redis 之后判断是否有数据 if(jedis.exists(key)){ //redis中有记录,无需执行指标办法 String json = jedis.get(key); //动静获取办法的返回值类型 向上造型 向下造型 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Class returnType = methodSignature.getReturnType(); result = ObjectMapperUtil.toObj(json,returnType); System.out.println("AOP查问redis缓存"); }else{ //示意数据不存在,须要查询数据库 result = joinPoint.proceed(); //执行指标办法及告诉 //将查问的后果保留到redis中去 String json = ObjectMapperUtil.toJSON(result); //判断数据是否须要超时工夫 if(cacheFind.seconds()>0){ jedis.setex(key,cacheFind.seconds(),json); }else { jedis.set(key, json); } System.out.println("aop执行指标办法查询数据库"); } } catch (Throwable throwable) { throwable.printStackTrace(); } jedis.close(); //将应用实现的链接记得敞开. return result; }}

November 12, 2020 · 1 min · jiezi

关于redis:阿里云-服务器ECS安装Redis

阿里云 服务器ECS装置Redis环境:阿里云服务器ECS抉择Centos 7.8 redis下载下载地址:http://redis.io/download,下载最新稳固版本。 wget http://download.redis.io/releases/redis-6.0.8.tar.gztar xzf redis-6.0.8.tar.gzcd redis-6.0.8yum -y install gcc # 如果不装置会编译报错make 批改redis配置文件vi redis.conf 批改 #bind 127.0.0.1 为bind 0.0.0.0 -> 容许所有主机拜访 将 daemonize no 改成 daemonize yes -> 设置redis能够始终在后盾运行,以守护过程形式运行,即敞开SSH工具程序也在运行。 明码设置,将”#requirepass foobared“ 取掉正文改成 requirepass 123456(或者其它你须要的明码) 保留并退出 启动rediscd src./redis-server ../redis.conf 阿里云服务器配置凋谢端口

November 12, 2020 · 1 min · jiezi

关于redis:Redis分片机制

为什么须要分片机制如果须要存储海量的内存数据,如果只应用一台redis,则无奈保障redis工作的效率。大量工夫都节约到了寻址中,所以须要一种机制可能满足该要求。采纳分片机制实现: Redis分片搭建搭建注意事项Redis服务的启动须要依赖于redis.conf的配置文件,如果须要筹备多台redis则须要多个redis.conf的配置。筹备端口号:1.63792.63803.6381 分片实现批改端口号:将各自的端口号进行批改1.进入各自的redis.conf文件中2.批改各自的端口号启动redis服务器校验服务器是否失常运行 对于分片的注意事项1.问题形容:当启动多台redis服务器之后,多台redis临时没有必然的分割,各自都是独立的实体,能够数据的存储。如图所示:2.如果将分片通过程序的形式进行操作,要把3太redis当做一个整体,所以与上述的操作齐全不同,不会呈现一个key同时保留到多个redis的景象。 分片入门案例/** * 测试Redis分片机制 * 思考: shards 如何确定应该存储到哪台redis中呢??? */ @Test public void testShards(){ List<JedisShardInfo> shards = new ArrayList<>(); shards.add(new JedisShardInfo("192.168.126.129",6379)); shards.add(new JedisShardInfo("192.168.126.129",6380)); shards.add(new JedisShardInfo("192.168.126.129",6381)); //筹备分片对象 ShardedJedis shardedJedis = new ShardedJedis(shards); shardedJedis.set("shards","redis分片测试"); System.out.println(shardedJedis.get("shards")); }一致性hash算法个别的hash是8为16禁止数。0---9 A--F 组合总共为2^32。如果对雷同的数据进行hash运算,后果必然雷同。一个数据1M和数据1G的hash运算的速度统一。 一致性hash算法介绍一致性哈希算法在1997年由麻省理工学院提出,是一种非凡的哈希算法,目标是解决分布式缓存的问题。 [1] 在移除或者增加一个服务器时,可能尽可能小地扭转已存在的服务申请与解决申请服务器之间的映射关系。一致性哈希解决了简略哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动静伸缩等问题。 个性平衡性概念:平衡性是指hash的后果应该平均分配到各个节点,这样从算法上解决了负载平衡问题。(大抵均匀)问题形容: 因为节点都是通过hash形式进行合计.所以可能呈现如图中的景象.,导致负载重大不均衡。解决办法:引入虚构节点 枯燥性特点:枯燥性是指在新增或者删减节点时,不影响零碎失常运行。 分散性分散性是指数据应该扩散地寄存在分布式集群中的各个节点(节点本人能够有备份),不用每个节点都存储所有的数据 。 SpringBoot整合Redis分片编辑配置文件# 配置redis单台服务器redis.host=192.168.126.129redis.port=6379# 配置redis分片机制redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381编辑配置类@Configuration@PropertySource("classpath:/properties/redis.properties")public class JedisConfig { @Value("${redis.nodes}") private String nodes; //node,node,node..... //配置redis分片机制 @Bean public ShardedJedis shardedJedis(){ nodes = nodes.trim(); //去除两边多余的空格 List<JedisShardInfo> shards = new ArrayList<>(); String[] nodeArray = nodes.split(","); for (String strNode : nodeArray){ //strNode = host:port String host = strNode.split(":")[0]; int port = Integer.parseInt(strNode.split(":")[1]); JedisShardInfo info = new JedisShardInfo(host, port); shards.add(info); } return new ShardedJedis(shards); } }批改AOP注入项 ...

November 12, 2020 · 1 min · jiezi

关于redis:数据库的redis-缓存

1.注意事项:1.数据结构的抉择 K-V构造 2.缓存不可能始终存储 须要优化 LRU算法3.缓存要求运行速度很快,C语言实现 运行在内存中4.如果缓存运行在内存中 忽然断电/宕机 导致内存间接失落 实现内存数据的长久化操作(磁盘) 2.redis1.下载redis 压缩包.tar.gztar -zxvf (指标压缩文件)改名2.进入redis 目录 cd redis/make (c语言编写 都要make)make install批改redis.conf 配置文件 改三处 3. 1.启动命令: redis-server redis.conf 2.检索命令: ps -ef | grep redis 3.进入redis: redis-cli -p 6379 敞开redis : redis-cli shutdownkill -9 (pid)

November 11, 2020 · 1 min · jiezi

关于redis:分布式锁和Redis实现

很多老手将 分布式锁 和 分布式事务 混同,集体了解:锁 是用于解决多程序并发抢夺某一共享资源;事务 是用于保障一系列操作执行的一致性。我后面有几篇文章解说了分布式事务,对于2PC、TCC和异步确保计划的实现,这次打算把几种分布式锁的计划说一说。 1. 定义在传统单体架构中,咱们最常见的锁是jdk的锁。因为线程是操作系统可能运行调度的最小单位,在java多线程开发时,就不免波及到不同线程竞争同一个过程下的资源。jdk库给咱们提供了synchronized、Lock和并发包java.util.concurrent.* 等。然而它们都对立的限度,竞争资源的线程,都是运行在同一个Jvm过程下,在分布式架构中,不同Jvm过程是无奈应用该锁的。 为了避免分布式系统中的多个过程之间互相烦扰,咱们须要一种分布式协调技术来对这些过程进行调度。而这个分布式协调技术的外围就是来实现这个分布式锁。 举个经典“超卖”的例子,某个电商我的项目中抢购100件库存的商品,抢购接口的逻辑可简略分为:1、查问库存是否大于零;2、当库存大于零时,购买商品。当只剩1件库存时,A用户和B用户都同时执行了第一步,查问库存都为1件,而后都执行购买操作。当他们购买实现,发现库存是 -1 件了。咱们能够在java代码中将“查问库存”和“减库存”的操作加锁,保障A用户和B用户的申请无奈并发执行。但万一咱们的接口服务是个集群服务,A用户和B用户的申请别离被负载平衡转发到不同的Jvm过程上,那还是解决不了问题。 2. 分布式锁比照通过后面的例子能够晓得,协调解决分布式锁的资源,必定不能是Jvm过程级别的资源,而应该是某个能够共享的内部资源。 三种实现形式常见分布式锁个别有三种实现形式:1. 数据库锁;2. 基于ZooKeeper的分布式锁;3. 基于Redis的分布式锁。 数据库锁:这种形式很容易被想到,把竞争的资源放到数据库中,利用数据库锁来实现资源竞争,能够参考之前的文章《数据库事务和锁》。例如:(1)乐观锁实现:查问库存商品的sql能够加上 "FOR UPDATE" 以实现排他锁,并且将“查问库存”和“减库存”打包成一个事务 COMMIT,在A用户查问和购买实现之前,B用户的申请都会被阻塞住。(2)乐观锁实现:在库存表中加上版本号字段来管制。或者更简略的实现是,当每次购买实现后发现库存小于零了,回滚事务即可。zookeeper的分布式锁:实现分布式锁,ZooKeeper是业余的。它相似于一个文件系统,通过多零碎竞争文件系统上的文件资源,起到分布式锁的作用。具体的实现形式,请参考之前的文章《zookeeper的开发利用》。redis的分布式锁:之前的文章讲过redis的开发利用和事务,始终没有讲过redis的分布式锁,这也是本文的核心内容。简略来说是通过setnx竞争键的值。“数据库锁”是竞争表级资源或行级资源,“zookeeper锁”是竞争文件资源,“redis锁”是为了竞争键值资源。它们都是通过竞争程序外的共享资源,来实现分布式锁。 比照不过在分布式锁的畛域,还是zookeeper更业余。redis实质上也是数据库,所有其它两种计划都是“兼职”实现分布式锁的,成果上没有zookeeper好。 性能耗费小:当真的呈现并发锁竞争时,数据库或redis的实现根本都是通过阻塞,或一直重试获取锁,有肯定的性能耗费。而zookeeper锁是通过注册监听器,当某个程序开释锁是,下一个程序监听到音讯再获取锁。锁开释机制欠缺:如果是redis获取锁的那个客户端bug了或者挂了,那么只能期待超时工夫之后能力开释锁;而zk的话,因为创立的是长期znode,只有客户端挂了,znode就没了,此时就主动开释锁。集群的强一致性:家喻户晓,zookeeper是典型实现了 CP 事务的案例,集群中永远由Leader节点来处理事务申请。而redis其实是实现 AP 事务的,如果master节点故障了,产生主从切换,此时就会有可能呈现锁失落的问题。锁的必要条件另外为了确保分布式锁可用,咱们至多要确保锁的实现同时满足以下几个条件: 互斥性。在任意时刻,只有一个客户端能持有锁。不会产生死锁。即便有一个客户端在持有锁的期间解体而没有被动解锁,也能保障后续其余客户端能加锁。解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端本人不能把他人加的锁给解了。3. Redis实现分布式锁3.1. 加锁正确的加锁public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 申请标识 * @param expireTime 超期工夫 * @return 是否获取胜利 */ public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; }}以看到,咱们加锁就一行代码:jedis.set(String key, String value, String nxxx, String expx, int time),这个set()办法一共有五个形参: ...

November 11, 2020 · 2 min · jiezi

关于redis:Redis中对Hash类型的操作命令

一、Redis 哈希(Hash)Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特地适宜用于存储对象。 Redis 中每个 hash 能够存储 232 - 1 键值对(40多亿)。 简略示例: 127.0.0.1:6379> HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000 OK 127.0.0.1:6379> HGETALL runoobkey 1) "name" 2) "redis tutorial" 3) "description" 4) "redis basic commands for caching" 5) "likes" 6) "20" 7) "visitors" 8) "23000"二、Hash类型的操作命令1、hsethset:设置值。格局是:hset hash的key 项的key 项的值 操作如下: ...

November 10, 2020 · 3 min · jiezi

关于redis:Redis持久化内存配置以及缓存问题的简单介绍

对于Redis配置阐明Redis长久化的阐明redis默认条件下反对数据的长久化操作,当redis中有数据时会定期将数据保留到磁盘中,当redis服务器重启时会依据配置文件读取指定的长久化文件,实现内存数据的复原。 长久化形式RDB模式特点:1.RDB模式是redis的默认的长久化策略。2.RDB模式记录的是redis内存数据的快照,最新的快照会笼罩之前的内容,所有RDB长久化文件占用空间更小,长久化的效率更高。3.RDB模式因为定期长久化,所以可能导致数据的失落。 命令: save 要求立刻马上长久化 同步的操作 其余的redis操作会陷入阻塞的状态.bgsave 开启后盾运行 异步的操作 因为是异步操作,所以无奈保障rdb文件肯定是最新的须要期待.配置:1.长久化文件名称2.长久化文件地位dir./ 相对路径的写法。dir/usr/local/src/redis 绝对路径的写法。3.RDB模式长久化策略 AOF模式特点:1.AOF模式默认条件下是敞开的,须要手动开启。2.AOF模式是异步的操作,记录的是用户的操作的过程,能够避免用户的数据失落。3.因为AOF模式记录的是程序的运行状态,所以长久化文件绝对较大,复原数据的工夫长, 须要人为的优化长久化文件。配置:总结:1.如果不容许数据失落,应用AOF模式。2.如果谋求效率,容许大量数据失落,采纳RDB模式。3.如果纪要保障效率,又要保证数据,则应该配置redis的集群,主机应用RDB模式,从机应用AOF模式。 对于Redis内存策略对于内存策略的阐明Redis数据的存储都在内存中.如果始终向内存中存储数据 必然会导致内存数据的溢出.解决形式: 尽可能为保留在redis中的数据增加超时工夫.利用算法优化旧的数据.LRU算法特点: 最好用的内存优化算法.LRU是Least Recently Used的缩写,即最近起码应用,是一种罕用的数据置换算法,抉择最近最久未应用的数据予以淘汰。该算法赋予每个数据一个拜访字段,用来记录一个数据自上次被拜访以来所经验的工夫 t,当须淘汰一个数据时,抉择现有数据中其 t 值最大的,即最近起码应用的数据予以淘汰。维度: 工夫 T LFU算法LFU(least frequently used (LFU) page-replacement algorithm)。即最不常常应用页置换算法,要求在页置换时置换援用计数最小的页,因为常常应用的页应该有一个较大的援用次数。然而有些页在开始时应用次数很多,但当前就不再应用,这类页将会长工夫留在内存中,因而能够将引用计数寄存器定时右移一位,造成指数衰减的均匀应用次数。维度: 应用次数 RANDOM算法即随机删除数据。 TTL算法把设定了超时工夫的数据将要移除的提前删除的算法。 Redis内存数据优化1.volatile-lru 设定了超时工夫的数据采纳lru算法。2.allkeys-lru 所有的数据采纳LRU算法。3.volatile-lfu 设定了超时工夫的数据采纳lfu算法删除。4.allkeys-lfu 所有数据采纳lfu算法删除。5.volatile-random 设定超时工夫的数据采纳随机算法。6.allkeys-random 所有数据的随机算法。7.volatile-ttl 设定超时工夫的数据的TTL算法。8.noeviction 如果内存溢出了 则报错返回. 不做任何操作. 默认值。 对于Redis缓存问题问题形容: 如果海量用户同时申请 而这时redis服务器呈现问题 则可能导致整个零碎解体.运行速度: tomcat服务器 150-250 之间 JVM调优 1000/秒NGINX 3-5万/秒REDIS 读 11.2万/秒 写 8.6万/秒 均匀 10万/秒缓存穿透问题形容: 因为用户高并发环境下拜访 数据库中不存在的数据时 ,容易导致缓存穿透.解决方案: 设定IP限流的操作 nginx中 或者微软服务机制 API网关实现. ...

November 9, 2020 · 1 min · jiezi

关于redis:Redis4个问题

Redis单线程为什么快?1). 纯内存操作2). 非阻塞的IO多路复用3). 单线程 防止了频繁的上下文切换 Redis如何删除缓存?定时删除+惰性删除1). 每隔100ms->随机抽一些key->查看过期工夫2). 查某个key时->查看过期工夫->过期则删除 Redis内存淘汰策略1). Noevict不删除->报错2). Allkey-lru:最近起码应用的key3). Allkey-random: 随机删除4). Volatile-lru: 有过期工夫的key中lru5). Volatile-random:有过期工夫的中随机删除6). Volatile-ttl: 有过期工夫的key中删更早的。 LruCacheLruCache<K,V> extends LinkedHashMap1). 构造方法true2). 成员变量 private int CASH_SIZE3). removeEldestEntry->return size()>CASH_SIZE

November 9, 2020 · 1 min · jiezi

关于redis:第三阶段-Day14-Redis分片机制-Redis哨兵机制

Redis分片机制============= 1.1 为什么须要分片机制如果须要存储海量的内存数据,如果只应用一台redis,无奈保障redis工作的效率. 大量的工夫都节约到了寻址当中.所以须要一种机制可能满足该要求.采纳分片机制实现: 1.2 Redis分片搭建1.2.1 搭建注意事项Redis服务的启动须要依赖于redis.conf的配置文件. 如果须要筹备3台redis.则须要筹备3个redis.conf的配置. 筹备端口号:1.63792.63803.6381 1.2.2 分片实现批改端口号: 将各自的端口号进行批改. 启动3台redis服务器校验服务器是否失常运行 1.2.3 对于分片的注意事项1.问题形容:当启动多台redis服务器之后,多台redis临时没有必然的分割,各自都是独立的实体.能够数据数据的存储.如图所示.2.如果将分片通过程序的形式进行操作,要把3台redis当做一个整体,所以与上述的操作齐全不同.不会呈现一个key同时保留到多个redis的景象. 1.3 分片入门案例 `/** * 测试Redis分片机制 * 思考: shards 如何确定应该存储到哪台redis中呢??? */ @Test public void testShards(){ List<JedisShardInfo> shards = new ArrayList<>(); shards.add(new JedisShardInfo("192.168.126.129",6379)); shards.add(new JedisShardInfo("192.168.126.129",6380)); shards.add(new JedisShardInfo("192.168.126.129",6381)); //筹备分片对象 ShardedJedis shardedJedis = new ShardedJedis(shards); shardedJedis.set("shards","redis分片测试"); System.out.println(shardedJedis.get("shards")); }` 1.4 一致性hash算法1.4.0 常识阐明常识1: 个别的hash是8位16进制数. 0-9 A-F (24)8 = 2^32常识2: 如果对雷同的数据进行hash运算 后果必然雷同的.常识3: 一个数据1M 与数据1G的hash运算的速度统一. 1.4.1 一致性hash算法介绍一致性哈希算法在1997年由麻省理工学院提出,是一种非凡的哈希算法,目标是解决分布式缓存的问题。 [1] 在移除或者增加一个服务器时,可能尽可能小地扭转已存在的服务申请与解决申请服务器之间的映射关系。一致性哈希解决了简略哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动静伸缩等问题 [2] 。 ...

November 9, 2020 · 2 min · jiezi

关于redis:第三阶段-Day13-AOP实现Redis缓存-redis基本用法持久化内存优化缓存击穿穿透雪崩

1 AOP实现Redis缓存1.1 如何了解AOP名称: 面向切面编程作用: 升高零碎中代码的耦合性,并且在不扭转原有代码的条件下对原有的办法进行性能的扩大.公式: AOP = 切入点表达式 + 告诉办法 1.2 告诉类型1.前置告诉 指标办法执行之前执行2.后置告诉 指标办法执行之后执行3.异样告诉 指标办法执行过程中抛出异样时执行4.最终告诉 无论什么时候都要执行的告诉特点: 上述的四大告诉类型 不能干涉指标办法是否执行.个别用来做程序运行状态的记录.监控 5.盘绕告诉 在指标办法执行前后都要执行的告诉办法 该办法能够控制目标办法是否运行.joinPoint.proceed(); 性能作为弱小的. 1.3 切入点表达式了解: 切入点表达式就是一个程序是否进入告诉的一个判断(IF)作用: 当程序运行过程中 ,满足了切入点表达式时才会去执行告诉办法,实现业务的扩大.品种(写法): bean(bean的名称 bean的ID) 只能拦挡具体的某个bean对象 只能匹配一个对象lg: bean(“itemServiceImpl”) within(包名.类名) within(“com.jt.service.*”) 能够匹配多个对象粗粒度的匹配准则 按类匹配 `3. execution(返回值类型 包名.类名.办法名(参数列表)) 最为弱小的用法 lg : execution(* com.jt.service..*.*(..)) 返回值类型任意 com.jt.service包下的所有的类的所有的办法都会被拦挡. 4.@annotation(包名.注解名称) 依照注解匹配.` * 1* 2* 3* 41.4 AOP入门案例`package com.jt.aop;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;import java.util.Arrays;@Aspect //我是一个AOP切面类@Component //将类交给spring容器治理public class CacheAOP { //公式 = 切入点表达式 + 告诉办法 /** * 对于切入点表达式的应用阐明 * 粗粒度: * 1.bean(bean的Id) 一个类 * 2.within(包名.类名) 多个类 * 细粒度 */ //@Pointcut("bean(itemCatServiceImpl)") //@Pointcut("within(com.jt.service..*)") //匹配多级目录 @Pointcut("execution(* com.jt.service..*.*(..))") //办法参数级别 public void pointCut(){ //定义切入点表达式 只为了占位 } //区别: pointCut() 示意切入点表达式的援用 实用于多个告诉 共用切入点的状况 // @Before("bean(itemCatServiceImpl)") 实用于单个告诉.不须要复用的 // 定义前置告诉,与切入点表达式进行绑定. 留神绑定的是办法 /** * 需要:获取指标对象的相干信息. * 1.获取指标办法的门路 包名.类名.办法名 * 2.获取指标办法的类型 class * 3.获取传递的参数 * 4.记录以后的执行工夫 */ @Before("pointCut()") //@Before("bean(itemCatServiceImpl)") public void before(JoinPoint joinPoint){ String className = joinPoint.getSignature().getDeclaringTypeName(); String methodName = joinPoint.getSignature().getName(); Class targetClass = joinPoint.getTarget().getClass(); Object[] args = joinPoint.getArgs(); Long runTime = System.currentTimeMillis(); System.out.println("办法门路:" +className+"."+methodName); System.out.println("指标对象类型:" + targetClass); System.out.println("参数:" + Arrays.toString(args)); System.out.println("执行工夫:" + runTime+"毫秒"); } /* @AfterReturning("pointCut()") public void afterReturn(){ System.out.println("我是后置告诉"); } @After("pointCut()") public void after(){ System.out.println("我是最终告诉"); }*/ /** * 盘绕告诉阐明 * 注意事项: * 1.盘绕告诉中必须增加参数ProceedingJoinPoint * 2.ProceedingJoinPoint只能盘绕告诉应用 * 3.ProceedingJoinPoint如果当做参数 则必须位于参数的第一位 */ @Around("pointCut()") public Object around(ProceedingJoinPoint joinPoint){ System.out.println("盘绕告诉开始!!!"); Object result = null; try { result = joinPoint.proceed(); //执行下一个告诉或者指标办法 } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("盘绕告诉完结"); return result; }}` 2 对于AOP实现Redis缓存2.1 自定义缓存注解问题: 如何管制 哪些办法须要应用缓存? cacheFind()解决方案: 采纳自定义注解的模式 进行定义,如果 办法执行须要应用缓存,则标识注解即可.对于注解的阐明:1.注解名称 : cacheFind2.属性参数 :2.1 key: 应该由用户本人手动增加 个别增加业务名称 之后动静拼接造成惟一的key2.2 seconds: 用户能够指定数据的超时的工夫 ...

November 9, 2020 · 3 min · jiezi

关于redis:第三阶段-Day12-Redis命令-SpringBoot整合redis-AoP实现Redis缓存

Redis入门案例============= 1.1 Redis常见用法1.1.1 setex学习`/** * 2.需要: * 1.向redis中插入数据 k-v * 2.为key设定超时工夫 60秒后生效. * 3.线程sleep 3秒 * 4.获取key的残余的存活工夫. * * 问题形容: 数据肯定会被删除吗?????? * 问题阐明: 如果应用redis 并且须要增加超时工夫时 个别须要满足原子性要求. * 原子性: 操作时要么胜利 要么失败.然而必须同时实现. */ @Test public void test02() throws InterruptedException { Jedis jedis = new Jedis("192.168.126.129",6379); jedis.setex("宝可梦", 60, "小火龙 妙蛙种子"); System.out.println(jedis.get("宝可梦")); /* Jedis jedis = new Jedis("192.168.126.129",6379); jedis.set("宝可梦", "小火龙 妙蛙种子"); int a = 1/0; //可能会出异样 jedis.expire("宝可梦", 60); Thread.sleep(3000); System.out.println(jedis.ttl("宝可梦"));*/ }` 1.1.2 setnx`/** * 3.需要如果发现key曾经存在时 不批改数据.如果key不存在时才会批改数据. * */ @Test public void test03() throws InterruptedException { Jedis jedis = new Jedis("192.168.126.129", 6379); jedis.setnx("aaaa", "测试nx的办法"); /*if(jedis.exists("aaa")){ System.out.println("key曾经存在 不做批改"); }else { jedis.set("aaa", "测试数据"); }*/ System.out.println(jedis.get("aaaa")); }` 1.1.3 set 超时工夫原子性操作 `/** * 需要: * 1.要求用户赋值时,如果数据存在则不赋值. setnx * 2.要求在赋值操作时,必须设定超时的工夫 并且要求满足原子性 setex */ @Test public void test04() throws InterruptedException { Jedis jedis = new Jedis("192.168.126.129", 6379); SetParams setParams = new SetParams(); setParams.nx().ex(20); jedis.set("bbbb", "实现业务操作AAAA", setParams); System.out.println(jedis.get("bbbb")); }` 1.1.4 list汇合练习 `@Test public void testList() throws InterruptedException { Jedis jedis = new Jedis("192.168.126.129", 6379); jedis.lpush("list", "1","2","3"); System.out.println(jedis.rpop("list")); }` 1.1.5 redis事务管制 `@Test public void testTx() throws InterruptedException { Jedis jedis = new Jedis("192.168.126.129", 6379); //1.开启事务 Transaction transaction = jedis.multi(); try { transaction.set("aa", "aa"); //提交事务 transaction.exec(); }catch (Exception e){ e.printStackTrace(); //回滚事务 transaction.discard(); } }` 2.秒杀业务逻辑—分布式锁机制6988 —1块 1部手机 20显示抢购胜利 并且领取了1块钱…问题:1.tomcat服务器有多台2.数据库数据只有1份3.必然会呈现高并发的景象.如何实现抢购… ...

November 9, 2020 · 3 min · jiezi

关于redis:Redis-持久化扫盲了

唠个嗑当初的面试要求是越来越难了,想当初毕业后面试开发岗位如果你会应用 Redis ,在面试官心中就会感觉,哎呦,你挺不错哦,算是加分项。当初的 Redis 成为了开发者的必备技能,面试如果没用过或不会用 Redis,那你就真的可能被劝退了。不停的学习新技术,或者就是开发者的宿命。 长久化Redis 能够用来做缓存,也属于 NoSQL 数据库,所以也反对数据长久化,Redis 数据库反对两种长久化计划: RDB 快照AOF 日志混合长久化RDB配置参数redis.conf 波及的次要配置 #1、主动备份规定(满足一个条件就会触发备份动作)save 900 1 #每隔900秒有1次批改则触发save 300 10 #每隔300秒有10次批改则触发save 60 10000 #每隔60秒有10000次批改则触发#2、是否快照备份呈现谬误后禁止客户端写入,默认是 yesstop-writes-on-bgsave-error yes#3、是否对快照文件进行压缩,默认 yesrdbcompression yes#4、是否对 RDB 文件进行校验,默认 yesrdbchecksum yes#5、定义生成的 RDB 文件名,默认 dump.rdbdbfilename dump.rdb#6、定义生成 RDB 文件目录,默认是启动 Redis 服务的目录dir ./刚装置好的 Redis,默认开启的是这种长久化形式,在启动服务的目录会备份一个 dump.rdb 文件,Redis 启动的时候会主动加载这个文件来复原备份的数据。备份咱们能够通过 Redis 客户端发送命令 save 手动备份以后数据的快照,然而 save 是阻塞命令,当备份文件过大,备份操作没有实现时,期间接管的其余操作命令将会被挂起。所以不倡议应用 save,这时候呈现了 bgsave,见名知意,它会 fork 一个子过程来解决备份操作,不影响主过程解决客户端申请命令。触发配置的主动备份策略,会主动执行 bgsave。执行 shutdown 命令,会触发 save 命令,备份实现后才会服务敞开。搭建主从复制时,在从机连上主机之后,会主动发送一条 sync 同步命令,主机收到命令之后,首先执行 bgsave 对数据进行快照备份,而后才会给从机发送快照数据进行同步。 AOF配置参数#1、开启 aof 配置,默认 noappendonly yes#2、定义生成的 AOF 文件名appendfilename "appendonly.aof"# 3、主动备份规定(抉择一个即可)# appendfsync always #每次批改都备份appendfsync everysec #每秒钟备份一次# appendfsync no #由操作系统主动调度刷磁盘#4、是否 aof 文件压缩时还持续进行同步操作,默认 nono-appendfsync-on-rewrite no#4、定义当目前 aof 文件大小超过上一次重写时的 aof 文件大小的百分之多少的时候,再次进行重写auto-aof-rewrite-percentage 100#5、如果之前没有重写过,则以启动时的 aof 大小为根据,同时要求 aof 文件至多要大于 64Mauto-aof-rewrite-min-size 64mb默认 AOF 是没有开启的,AOF 长久化是将被执行的命令追加到 AOF 文件尾部,数据恢复时把命令从头到尾执行一遍应用 AOF 形式做长久化,能够把 RDB 长久化的策略正文掉save ""#save 900 1#save 300 10#save 60 10000混合长久化此性能是 Redis4 之后新增的,说实话我也是前几天刚理解到的,接触的不多,这里也简略做个介绍吧,想深刻的那只能让您悲观了,出门左拐直走......配置参数aof-use-rdb-preamble yes备份形式通过下面参数设为 yes 来开启,在数据写入的时候先把数据以 RDB 的格局放在文件结尾,再将后续的命令以 AOF 的格局追加到文件前面,这样算是引进了 RDB 数据恢复速度快的长处 和 AOF 数据失落危险小的长处。 ...

November 7, 2020 · 1 min · jiezi

关于redis:Redis多机功能Sentinel

Redis的主从复制模式下,一旦主节点因为故障不能提供服务,须要人工将从节点降职为主节点,同时还要告诉利用方更新主节点地址,对于很多利用场景这种故障解决的形式是无奈承受的。Redis从2.8版本开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。 基本概念 主从复制的问题Redis的主从复制模式能够将主节点的数据扭转同步给从节点,这样从节点就能够起到两个作用:第一,作为主节点的一个备份,一旦主节点出了故障不可达的状况,从节点能够作为后备“顶”上来,并且保证数据尽量不失落(主从复制是最终一致性)。第二,从节点能够扩大主节点的读能力,一旦主节点不能支撑住大并发量的读操作,从节点能够在肯定水平上帮忙主节点分担读压力。 然而主从复制也带来了以下问题: 一旦主节点呈现故障,须要手动将一个从节点降职为主节点,同时须要批改利用方的主节点地址,还须要命令其余从节点去复制新的主节点,整个过程都须要人工干预。主节点的写能力受到单机的限度。主节点的存储能力受到单机的限度。其中第一个问题就是Redis的高可用问题,第二、三个问题属于Redis的分布式问题,会在“集群”外面介绍。 高可用Redis主从复制模式下,一旦主节点呈现了故障不可达,须要人工干预进行故障转移,无论对于Redis的利用方还是运维方都带来了很大的不便。对于利用方来说无奈及时感知到主节点的变动,必然会造成肯定的写数据失落和读数据谬误,甚至可能造成利用方服务不可用。对于Redis的运维方来说,整个故障转移的过程是须要人工来染指的,故障转移实时性和准确性上都无奈失去保障。 思考到这点,有些公司把故障转移流程自动化了,然而依然存在如下问题:第一,判断节点不可达的机制是否健全和规范。第二,如果有多个从节点,怎么保障只有一个被降职为主节点。第三,告诉客户端新的主节点机制是否足够强壮。Redis Sentinel正是用于解决这些问题。 Redis Sentinel的高可用性Redis Sentinel是一个分布式架构,其中蕴含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其余Sentinel节点进行“协商”,当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来实现主动故障转移的工作,同时会将这个变动实时告诉给Redis利用方。整个过程齐全是主动的,不须要人工来染指,所以这套计划很无效地解决了Redis的高可用问题。 从逻辑架构上看,Sentinel节点汇合会定期对所有节点进行监控,特地是对主节点的故障实现主动转移。上面以1个主节点、2个从节点、3个Sentinel节点组成的Redis Sentinel为例子进行阐明,拓扑构造如图所示。 整个故障转移的解决逻辑有上面4个步骤: 主节点呈现故障,此时两个从节点与主节点失去连贯,主从复制失败。每个Sentinel节点通过定期监控发现主节点呈现了故障。多个Sentinel节点对主节点的故障达成统一,选举出sentinel-3节点作为领导者负责故障转移。Sentinel领导者节点执行了故障转移,整个过程是自动化实现的。 通过下面介绍的Redis Sentinel逻辑架构以及故障转移的解决,能够看出Redis Sentinel具备以下几个性能: 监控:Sentinel节点会定期检测Redis数据节点、其余Sentinel节点是否可达。告诉:Sentinel节点会将故障转移的后果告诉给利用方。主节点故障转移:实现从节点降职为主节点并保护后续正确的主从关系。配置提供者:在Redis Sentinel构造中,客户端在初始化的时候连贯的是Sentinel节点汇合,从中获取主节点信息。同时看到,Redis Sentinel蕴含了若个Sentinel节点,这样做也带来了两个益处: 对于节点的故障判断是由多个Sentinel节点共同完成,这样能够无效地避免误判。Sentinel节点汇合是由若干个Sentinel节点组成的,这样即便个别Sentinel节点不可用,整个Sentinel节点汇合仍然是强壮的。Sentinel节点自身就是独立的Redis节点,只不过它们有一些非凡,它们不存储数据,只反对局部命令。 装置和部署上面将以3个Sentinel节点、1个主节点、2个从节点组成一个RedisSentinel进行阐明。 部署流程Redis Sentinel中Redis数据节点没有做任何非凡配置,依照惯例办法启动就能够。3个Sentinel节点的部署办法是完全一致的(端口不同),上面以sentinel-1节点的部署为例子进行阐明。 配置Sentinel节点// redis-sentinel-26379.confport 26379daemonize yeslogfile "26379.log"dir /opt/soft/redis/datasentinel monitor mymaster 127.0.0.1 6379 2sentinel down-after-milliseconds mymaster 30000sentinel parallel-syncs mymaster 1sentinel failover-timeout mymaster 180000Sentinel节点的默认端口是26379,sentinel monitor mymaster 127.0.0.1 6379 2配置代表sentinel-1节点须要监控127.0.0.1:6379这个主节点,2代表判断主节点失败至多须要2个Sentinel节点批准,mymaster是主节点的别名,其余Sentinel配置将在当前进行具体阐明。 启动Sentinel节点Sentinel节点的启动办法有两种: 1.应用redis-sentinel命令: redis-sentinel redis-sentinel-26379.conf2.应用redis-server命令加--sentinel参数: redis-server redis-sentinel-26379.conf --sentinel两种办法实质上是一样的。 确认Sentinel节点实质上是一个非凡的Redis节点,所以也能够通过info命令来查问它的相干信息,从上面info的Sentinel片段来看,Sentinel节点找到了主节点127.0.0.1:6379,发现了它的两个从节点,同时发现Redis Sentinel一共有3个Sentinel节点。这里只须要理解Sentinel节点可能彼此感知到对方,同时可能感知到Redis数据节点就能够了: $ redis-cli -h 127.0.0.1 -p 26379 info Sentinelsentinel_masters:1sentinel_tilt:0sentinel_running_scripts:0sentinel_scripts_queue_length:0master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3当三个Sentinel节点都启动后,整个拓扑构造如图所示。至此Redis Sentinel曾经搭建起来了,整体上还是比拟容易的,然而有两点须要强调一下: ...

November 7, 2020 · 2 min · jiezi

关于redis:Redis进阶阻塞

Redis是典型的单线程架构,所有的读写操作都是在一条主线程中实现的。当Redis用于高并发场景时,这条线程就变成了它的生命线。如果呈现阻塞,哪怕是很短时间,对于咱们的利用来说都是噩梦。 发现阻塞当Redis阻塞时,线上应用服务应该最先感知到,这时利用方会收到大量Redis超时异样,比方Jedis客户端会抛出JedisConnectionException异样。常见的做法是在利用方退出异样统计并通过邮件/短信/微信报警,以便及时发现告诉问题。开发人员须要解决如何统计异样以及触发报警的机会。何时触发报警个别依据利用的并发量决定,如1分钟内超过10个异样触发报警。在实现异样统计时要留神,因为Redis调用API会扩散在我的项目的多个中央,每个中央都监听异样并退出监控代码必然难以保护。这时能够借助于日志零碎,如Java语言能够应用logback或log4j。当异样产生时,异样信息最终会被日志零碎收集到Appender(输入目的地),默认的Appender个别是具体的日志文件,能够自定义一个Appender,用于专门统计异样和触发报警逻辑。 借助日志零碎统计异样的前提是,须要我的项目必须应用日志API进行异样对立输入,比方所有的异样都通过logger.error打印,这应该作为开发标准推广。其余编程语言也能够采纳相似的日志零碎实现异样统计报警。利用方退出异样监控之后还存在一个问题,当开发人员接到异样报警后,通常会去线上服务器查看谬误日志细节。这时如果利用操作的是多个Redis节点(比方应用Redis集群),如何决定是哪一个节点超时还是所有的节点都有超时呢?这是线上很常见的需要,但绝大多数的客户端类库并没有在异样信息中打印ip和port信息,导致无奈疾速定位是哪个Redis节点超时。不过批改Redis客户端老本很低,比方Jedis只须要批改Connection类下的connect、sendCommand、readProtocolWithCheckingBroken办法专门捕捉连贯,发送命令,协定读取事件的异样。因为客户端类库都会保留ip和port信息,当异样产生时很容易打印出对应节点的ip和port,辅助咱们疾速定位问题节点。 除了在利用方退出统计报警逻辑之外,还能够借助Redis监控零碎发现阻塞问题,当监控零碎检测到Redis运行期的一些要害指标呈现不失常时会触发报警。Redis相干的监控零碎开源的计划有很多,一些公司外部也会本人开发监控零碎。一个牢靠的Redis监控零碎首先须要做到对要害指标全方位监控和异样辨认,辅助开发运维人员发现定位问题。如果Redis服务没有引入监控零碎作辅助撑持,对于线上的服务是十分不负责任和危险的。 外在起因API或数据结构应用不合理如何发现慢查问Redis原生提供慢查问统计性能,执行slowlog get{n}命令能够获取最近的n条慢查问命令,默认对于执行超过10毫秒的命令都会记录到一个定长队列中,线上实例倡议设置为1毫秒便于及时发现毫秒级以上的命令。慢查问队列长度默认128,可适当调大。慢查问自身只记录了命令执行工夫,不包含数据网络传输工夫和命令排队工夫,因而客户端产生阻塞异样后,可能不是以后命令迟缓,而是在期待其余命令执行。须要重点比对异样和慢查问产生的工夫点,确认是否有慢查问造成的命令阻塞排队。 发现慢查问后,开发人员须要作出及时调整。能够依照以下两个方向去调整: 批改为低算法度的命令,如hgetall改为hmget等,禁用keys、sort等命令。缩减大对象数据或把大对象拆分为多个小对象,避免一次命令操作过多的数据。大对象拆分过程须要视具体的业务决定,如用户好友汇合存储在Redis中,有些热点用户会关注大量好友,这时能够按工夫或其余维度拆分到多个汇合中。如何发现大对象Redis自身提供发现大对象的工具,对应命令:redis-cli -h {ip} -p {port} bigkeys。外部原理采纳分段进行scan操作,把历史扫描过的最大对象统计进去便于剖析优化,依据后果汇总信息能十分不便地获取到大对象的键,以及不同类型数据结构的应用状况。 CPU饱和单线程的Redis解决命令时只能应用一个CPU。而CPU饱和是指Redis把单核CPU使用率跑到靠近100%。应用top命令很容易辨认出对应Redis过程的CPU使用率。CPU饱和是十分危险的,将导致Redis无奈解决更多的命令,重大影响吞吐量和利用方的稳定性。 对于这种状况,首先判断以后Redis的并发量是否达到极限,倡议应用统计命令redis-cli -h {ip} -p {port} --stat获取以后Redis应用状况,该命令每秒输入一行统计信息。 对于这种状况,垂直层面的命令优化很难达到成果,这时就须要做集群化程度扩大来摊派OPS压力。如果只有几百或几千OPS的Redis实例就靠近CPU饱和是很不失常的,有可能应用了高算法复杂度的命令。还有一种状况是适度的内存优化,这种状况有些荫蔽,须要咱们依据info commandstats统计信息剖析出命令不合理开销工夫。 例如Redis实例为了谋求低内存使用量,适度放宽ziplist应用条件(批改了hash-max-ziplist-entries和hash-max-ziplist-value配置)。过程内的hash对象均匀存储着上万个元素,而针对ziplist的操作算法复杂度在O(n)到O(n2)之间。尽管采纳ziplist编码后hash构造内存占用会变小,然而操作变得更慢且更耗费CPU。ziplist压缩编码是Redis用来均衡空间和效率的优化伎俩,不可适度应用。 长久化阻塞fork阻塞fork操作产生在RDB和AOF重写时,Redis主线程调用fork操作产生共享内存的子过程,由子过程实现长久化文件重写工作。如果fork操作自身耗时过长,必然会导致主线程的阻塞。 能够执行info stats命令获取到latest_fork_usec指标,示意Redis最近一次fork操作耗时,如果耗时很大,比方超过1秒,则须要做出优化调整,如防止应用过大的内存实例和躲避fork迟缓的操作系统等。 AOF刷盘阻塞当咱们开启AOF长久化性能时,文件刷盘的形式个别采纳每秒一次,后盾线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作须要期待,直到写入实现。如果主线程发现间隔上一次的fsync胜利超过2秒,为了数据安全性它会阻塞直到后盾线程执行fsync操作实现。这种阻塞行为次要是硬盘压力引起,能够查看Redis日志辨认出这种状况,也能够查看info persistence统计中的aof_delayed_fsync指标,每次产生fdatasync阻塞主线程时会累加。 HugePage写操作阻塞子过程在执行重写期间利用Linux写时复制技术升高内存开销,因而只有写操作时Redis才复制要批改的内存页。对于开启Transparent HugePages的操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512倍,会拖慢写操作的执行工夫,导致大量写操作慢查问。例如简略的incr命令也会呈现在慢查问中。 外在起因CPU竞争过程竞争Redis是典型的CPU密集型利用,不倡议和其余多核CPU密集型服务部署在一起。当其余过程适度耗费CPU时,将重大影响Redis吞吐量。能够通过top、sar等命令定位到CPU耗费的工夫点和具体过程,这个问题比拟容易发现,须要调整服务之间部署构造。 绑定CPU部署Redis时为了充分利用多核CPU,通常一台机器部署多个实例。常见的一种优化是把Redis过程绑定到CPU上,用于升高CPU频繁上下文切换的开销。这个优化技巧失常状况下没有问题,然而存在例外情况。 当Redis父过程创立子过程进行RDB/AOF重写时,如果做了CPU绑定,会与父过程共享应用一个CPU。子过程重写时对单核CPU使用率通常在90%以上,父过程与子过程将产生强烈CPU竞争,极大影响Redis稳定性。因而对于开启了长久化或参加复制的主节点不倡议绑定CPU。 内存替换内存替换(swap)对于Redis来说是十分致命的,Redis保障高性能的一个重要前提是所有的数据在内存中。如果操作系统把Redis应用的局部内存换出到硬盘,因为内存与硬盘读写速度差几个数量级,会导致产生替换后的Redis性能急剧下降。辨认Redis内存替换的查看办法如下: 1)查问Redis过程号: redis-cli -p 6383 info server | grep process_idprocess_id:44762)依据过程号查问内存替换信息: cat /proc/4476/smaps | grep Swap如果交换量都是0KB或者个别的是4KB,则是失常景象,阐明Redis过程内存没有被替换。预防内存替换的办法有: 保障机器短缺的可用内存。确保所有Redis实例设置最大可用内存(maxmemory),避免极其状况下Redis内存不可控的增长。升高零碎应用swap优先级,如echo10 > /proc/sys/vm/swappiness。网络问题连贯回绝当呈现网络闪断或者连接数溢出时,客户端会呈现无奈连贯Redis的状况。咱们须要辨别这三种状况:网络闪断、Redis连贯回绝、连贯溢出。 1) 网络闪断 个别产生在网络割接或者带宽耗尽的状况,对于网络闪断的辨认比拟难,常见的做法能够通过sar-n DEV查看本机历史流量是否失常,或者借助内部系统监控工具(如Ganglia)进行辨认。具体问题定位须要更下层的运维反对,对于重要的Redis服务须要充分考虑部署架构的优化,尽量避免客户端与Redis之间异地跨机房调用。 2) Redis连贯回绝 Redis通过maxclients参数管制客户端最大连接数,默认10000。当Redis连接数大于maxclients时会回绝新的连贯进入,info statsrejected_connections统计指标记录所有被回绝连贯的数量。 Redis应用多路复用IO模型可撑持大量连贯,然而不代表能够无限连接。客户端拜访Redis时尽量采纳NIO长连贯或者连接池的形式。 当Redis用于大量分布式节点拜访且生命周期比拟短的场景时,如比拟典型的在Map/Reduce中应用Redis。因为客户端服务存在频繁启动和销毁的状况且默认Redis不会被动敞开长时间闲置连贯或查看敞开有效的TCP连贯,因而会导致Redis连接数疾速耗费且无奈开释的问题。这种场景下倡议设置tcp-keepalive和timeout参数让Redis被动检查和敞开有效连贯。 3) 连贯溢出 过程限度(ulimit)backlog队列溢出网络提早网络提早取决于客户端到Redis服务器之间的网络环境。次要包含它们之间的物理拓扑和带宽占用状况。 网络提早问题经常出现在跨机房的部署构造上,对于机房之间提早比较严重的场景须要调整拓扑构造,如把客户端和Redis部署在同机房或同城机房等。 带宽占用次要依据过后使用率是否达到瓶颈无关,如频繁操作Redis的大对象对于千兆网卡的机器很容易达到网卡瓶颈,因而须要重点监控机器流量,及时发现网卡打满产生的网络提早或通信中断等状况,而机房专线和交换机带宽个别由下层运维监控反对,通常呈现瓶颈的概率较小。 ...

November 6, 2020 · 1 min · jiezi

关于redis:集成Redismybatisspringboot

创立我的项目第一步当然是创立一个springBoot我的项目,并导入依赖嘛。这就不多说了。这儿咱们就不必jedis了,spring对redis也有反对,咱们就用spring-boot-starter-data-redis来整合redis。 <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.3.5.RELEASE</version></dependency>写配置spring: #redis 的配置 redis: host: localhost port: 6379 database: 0# 数据源,我用了druid datasource: type: com.alibaba.druid.pool.DruidDataSource password: 12345678 username: root url: jdbc:mysql://localhost:3306/redis?characterEncoding=UTF-8 druid: stat-view-servlet: url-pattern: /druid/* login-password: 123456 login-username: admin#mybatis 的配置mybatis: mapper-locations: classpath:/mapper/*.xml# 配置日志打印logging: level: com.tao.redis_demo_springboot.dao: debug## 环境 咱们来搭建根本的一个增删该查 咱们新建一个测试类,来测试一下那咱们该如何让redis进行缓存呢?在mybatis中,咱们能够通过cache标签来开启二级缓存,这个默认的缓存是org.apache.ibatis.cache.impl.PerpetualCache来实现的。在cache标签中,type能够指定缓存类。那咱们能够自定义一个缓存类,用springboot提供的redistemplate 来对redis进行操作。也就是说,咱们通过这个自定义的缓存类来操作redis,咱们也就胜利地用redis来做缓存了。 自定义缓存类那咱们如何来定义一个缓存类呢?咱们能够看看mybatis他是如何实现的,咱们能够照猫画虎,去看看PerpetualCache的源码。 public class PerpetualCache implements Cache { private final String id; private final Map<Object, Object> cache = new HashMap<>(); public PerpetualCache(String id) { this.id = id; } @Override public String getId() { return id; } @Override public int getSize() { return cache.size(); } @Override public void putObject(Object key, Object value) { cache.put(key, value); } @Override public Object getObject(Object key) { return cache.get(key); } @Override public Object removeObject(Object key) { return cache.remove(key); } @Override public void clear() { cache.clear(); } @Override public boolean equals(Object o) { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } if (this == o) { return true; } if (!(o instanceof Cache)) { return false; } Cache otherCache = (Cache) o; return getId().equals(otherCache.getId()); } @Override public int hashCode() { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } return getId().hashCode(); }}一看源码就很清晰了,他是用一个map来治理缓存。那能够把缓存在redis中也写成一个map的格局。 ...

November 6, 2020 · 1 min · jiezi

关于redis:redis的stream类型命令详解

前言最近我的项目中应用到了 Redis 中的 stream 数据类型作为音讯队列应用,相比于其余 redis 实现的音讯队列更加不便。因为是第一次应用,记录下知识点当前备用。 Stream类型基于 redis 的音讯队列有好多种实现,然而大多都有其特点和问题,自身 redis 只是个缓存啊????,预计官网都看不下去了,这才在 redis 5.0 里加了一种数据类型专门用来实现典型的音讯队列。 stream 类型简直具备了一个音讯队列所须要用到的所有性能,包含但不限于: 音讯 ID 的序列化生成音讯遍历解决未确认的音讯音讯的阻塞和非阻塞读取音讯的分组生产音讯队列监控等等.... 上面介绍 stream 数据类型的应用办法。 stream类型的应用xadd命令语法格局为: XADD key ID field value [field value ...] key,用来指定 stream 的名字ID,用来指定 ID 值,最罕用的是 *field value [field value ...],key-value类型数据xadd 用来在指定的 key 中增加音讯,如果 key 不存在,则主动创立。增加的音讯为 key-value 类型,能够一次增加多个音讯。 指定 ID,最罕用的是 *,示意由 redis 主动生成 ID,主动生成的 ID 为 1526919030474-55 格局,由毫秒工夫戳和序列号组成,序列号用于辨别同一毫秒内生成的音讯,保障 ID 始终是递增的。如果因为一些其余起因零碎时钟慢了,导致生成的工夫戳小于了 redis 中记录的值,则会取零碎中记录的最大值持续递增,保障 ID 的递增状态。 127.0.0.1:6379> xadd message 1 key1 value1 key2 value2"1-0"127.0.0.1:6379> xadd message 1-2 key1 value1 key2 value2"1-2"ID 在个别状况下是由 redis 主动指定的,但其实 ID 也是能够自定义的,为了保障 ID 的自增状态,手动指定的 ID 必须要大于零碎中存在的 ID,只不过个别不这么做。 ...

November 5, 2020 · 7 min · jiezi

关于redis:redis五种数据类型的应用

redis的五种数据类型和应用场景 string类型 string类型多用于缓存 set key value(value能够为json字符串)setnx多用于分布式锁(前面具体整顿) 计数器 incr article:{文章id}:readcountget article:{文章id}:readcountweb集群session共享redis实现session共享https://www.cnblogs.com/cxx8181602/p/9759645.html 分布式系统全局序列号(分库分表的主键能够应用此办法 批量生成id会晋升性能) incrby orderid 1000setbit的位运算https://www.jianshu.com/p/3a30f58ba62c hash类型 对象存储 mset user {user_id}:name test {user_id}:age 12hget user {user_id}:name {user_id}:age 因为redis是单线程操作,有一个十分大的禁忌就是不要让key太大,会导致执行该命令工夫十分长,会阻塞线程,所以hash不要当作数据库来用,只是存储一些热数据就行在理论利用中,能够给hash的key来分段,有一点相似于数据库分表那种思路,把数据存储在不同的key中,切记,千万不要让一个key过大 能够用来实现购物车性能实现形式如下图 以用户id为key以商品id为field商品数量为value购物车操作流程 增加商品 hset cart:123 10010 1(123为user_id 10010为商品id)减少数量 hincrby cart:123 10010 1商品总数 hlen cart:123删除商品 hdel cart:123 10010获取购物车所有商品 hgetall cart:123和string相比的优缺点 长处 同类数据归档,存储比拟不便比string耗费的cpu更小比string更节俭存储空间毛病 过期性能不能用在field上,只能用在key上不适宜在集群架构下大规模应用(集群数据都是分片解决的,目标是让数据分段平均的存储,比方把user表的信息都存在hash中,就会导致那个key十分大,这样就会导致某一个redis机器上的数据十分大,导致了数据歪斜)list类型 能够实现常见的栈和队列的数据结构,如下图 阻塞队列 Blocking MQ(阻塞队列) = LPUSH + BRPOP( BRPOP会始终期待) 微信,微博音讯流 博主发消息间接发到粉丝的信息list中,粉丝间接读取即可,然而这种只适宜粉丝比拟少的状况 set类型利用场景 微信抽奖流动 点击参加抽奖 sadd key {user_id}查看所有抽奖用户 smambers key抽取count名中奖者 srandmember key count 或者 spop key count(spop从汇合中取出数据后会删除掉 适宜不能反复抽奖的场景) 微信微博点赞的实现 ...

November 4, 2020 · 1 min · jiezi