关于redis:windows系统注册redis-为服务自动启动

以后redis版本:3.2.100 通常状况下咱们能够通过 redis-server.exe 和配置文件启动redis服务 : redis-server.exe redis.windows.conf 另外开启一个命令行窗口 redis-cli.exe 即可做一些简略的操作命令行 但如果咱们敞开控制台,那么Redis服务也跟随着一起敞开了,想应用的时候又得执行命令从新开启动redis 服务,是十分低效又麻烦的。 在Windows中有个本地服务的概念,咱们的指标就是将Redis注册成这外面的一个服务,而后就能够不受控制台退出的影响了。 注册为本地服务 redis-server.exe --service-install redis.windows.conf 从图中看到已胜利受权并且注册胜利,接下来,咱们到windows服务(右键单击windows菜单-》计算机管理-》服务和应用程序-》服务)中去看一下是否有redis服务: 咱们可能发现计算机中曾经有十分多的服务了,并且Redis也在其中,阐明咱们真的注册胜利了。 此时咱们用客户端连贯是不行的,因为还没有启动。 开启Redis服务 办法一:选中Redis项右击-》启动 办法二:redis-server --service-start 开启胜利后,能够看到Redis项状态变为 正在运行,如下图: 到这里,咱们就能够用 redis-cli 胜利连贯redis服务了。 命令规整 注册服务 redis-server --service-install redis.windows.conf删除服务 redis-server --service-uninstall 开启服务 redis-server --service-start 进行服务 redis-server --service-stop 创立多个Redis实例 step1: 复制一份redis.windows.conf 配置文件,改名为 redis.windows10001.conf step2:更改 redis.windows10001.conf 配置文件的信息 端口号 port 为 10001 其余先不作阐明 step3:注册为windows服务 redis-server.exe --service-install redis.windows10001.conf --service-name redis10001 --port 10001 从windows服务中能够看到,有两个redis服务,方才注册的是redis10001,服务还未开启,如下图所示:

June 3, 2021 · 1 min · jiezi

关于redis:REDIS事件之EventLoop

什么是EventLoop单线程就意味着,所有工作须要排队,前一个工作完结,才会执行后一个工作。如果前一个工作耗时很长,后一个工作就不得不始终等着。如果排队是因为计算量大,CPU忙不过来,倒也算了,然而很多时候CPU是闲着的,因为IO设施(输入输出设施)很慢(比方Ajax操作从网络读取数据),不得不等着后果进去,再往下执行。于是,所有工作能够分成两种,一种是同步工作(synchronous),另一种是异步工作(asynchronous)。同步工作指的是,在主线程上排队执行的工作,只有前一个工作执行结束,能力执行后一个工作;异步工作指的是,不进入主线程、而进入"工作队列"(task queue)的工作,只有"工作队列"告诉主线程,某个异步工作能够执行了,该工作才会进入主线程执行。 具体来说,异步执行的运行机制如下。 (1)所有同步工作都在主线程上执行,造成一个执行栈(execution context stack)。(2)主线程之外,还存在一个"工作队列"(task queue)。只有异步工作有了运行后果,就在"工作队列"之中搁置一个事件。(3)一旦"执行栈"中的所有同步工作执行结束,零碎就会读取"工作队列",看看外面有哪些事件。那些对应的异步工作,于是完结期待状态,进入执行栈,开始执行。(4)主线程一直反复下面的第三步。redis启动后初始化工作完结后,即进入期待工作的循环过程中。aeMain函数, ae.c/aeMain函数 void aeMain(aeEventLoop *eventLoop) { while (!eventLoop->stop) { aeProcessEvents(eventLoop, AE_ALL_EVENTS); }}ae.h/aeEventLoop struct aeEventLoop { int setsize; // 最大事件数量 void *apidata; // io事件数据,见ae_epoll.c/aeApiState struct aeFileEvent *events; // 注册事件列表,fd为下标,见ae.h/aeFileEvent}ae.h/aeFileEvent struct aeFileEvent { int mask; // one of AE_(READABLE|WRITABLE),事件类型 aeFileProc *rfileProc; // READABLE事件处理器 aeFileProc *wfileProc; // WRITABLE事件处理器 void *clientData; // 客户端数据}

May 30, 2021 · 1 min · jiezi

关于redis:Redis内存淘汰机制

1.Redis过期删除在应用redis存储数据时,咱们个别会对数据设置过期工夫,使得这些缓存在过期之后能被革除,开释宝贵的缓存资源。那过期清理是用什么策略来实现的呢? redis次要通过以下两种形式 1.1 定期删除1.redis每过100ms,从设置了过期工夫的key中随机取出20个缓存key 2.革除其中的过期key 3.若过期key占比超过1/4,则反复步骤1 为什么定期删除采纳的是随机策略,而不是对全副数据做清理呢?因为每100ms过滤所有缓存数据,对CPU压力较大。 尽管定期删除解决了一部分过期数据的问题,然而还有不少数据并没有被革除出缓存,所以此时就有了惰性删除 1.2 惰性删除某个缓存key在查问时,若此时已过期,则会从缓存中删除,同时返回空这种形式是被动触发的, 定期删除与惰性删除尽管能清理一部分过期数据,但还存在一个问题: 局部过期缓存key未被清理出缓存,短暂占用缓存资源(随机策略存在的缺点性),随着缓存数据的一直减少, 无奈通过删除过期key的形式腾出空间,来贮存新的热点数据。 这种状况下,如何淘汰旧的缓存数据,贮存新的热点数据呢?内存淘汰机制 2.内存淘汰机制redis提供8种策略来应答当应用内存达到限度值的状况 1.noeviction: 返回谬误,不删除任何键值 2.allkeys-lru:尝试回收起码应用的键值(LRU算法) 3.volatile-lru:尝试回收起码应用的键值,但仅限于在过期键值汇合中 4.allkeys-random:回收随机的键值 5.volatile-random:回收随机的键值,但仅限于在过期键值汇合中 6.volatile-ttl:回收过期汇合的键值,并优先回收存活工夫较短的键值 7.allkeys-lfu:回收起码应用频次的键值(LFU算法) 8.volatile-lfu:回收起码应用频次的键值(LFU算法),但仅限于在过期键值汇合中 这里有两个重要的算法: LRU:最近起码被应用。拜访工夫越早越容易被淘汰 LFU:最近起码应用频次。应用频次越少越容易被淘汰 Redis的LRU算法采纳一种近似LRU的形式来实现,通过对大量keys(maxmemory-samples,默认为5)进行取样,而后回收其中一个最好的key(被拜访工夫最早的)。 Redis3.0算法已改良为回收键的候选池子 1.第一次随机选取的key都放入一个pool中(pool大小为16),pool中的key是依照拜访工夫大小排序; 2.接下来每次随机选取的key都必须小于pool中最小的key,若pool未填满,则反复步骤1 3.放满之后,每次有新的key须要进入时,须要将pool中lru最大的一个key取出 4.淘汰的时候,间接从pool中取出一个lru最小的一个key而后淘汰 Redis有了LRU之后,为什么还须要LFU呢?因为Redis作者发现就算进步采样数量或者pool的大小,也无奈再进步缓存命中率,而LFU算法能起到更好的成果。 LFU近似于LRU,它应用一个概率计数器(morris counter),用来预计拜访频率;counter的计数有两个特点,1.随着拜访次数的减少,counter的计数会越来越迟缓(counter最大值为255),2.随着工夫的流逝,counter会逐步衰减。淘汰时也会有一个pool,也采取与LRU相似的形式,然而排序是依照计数从大到小排列(越靠后越容易被淘汰)为什么Redis不采纳规范LRU算法: 规范LRU算法为了达到查找和删除的工夫复杂度个别采纳hash表和双向链表联合的数据结构。这样会减少额定的内存占用。

May 29, 2021 · 1 min · jiezi

关于redis:Redis-集群化方案对比CodisTwemproxyRedis-Cluster

之前咱们提到,为了保障Redis的高可用,次要须要以下几个方面: 数据长久化主从复制主动故障复原集群化咱们简略理一下这几个计划的特点,以及它们之间的分割。 数据长久化实质上是为了做数据备份,有了数据长久化,当Redis宕机时,咱们能够把数据从磁盘上复原回来,但在数据恢复之前,服务是不可用的,而且数据恢复的工夫取决于实例的大小,数据量越大,复原起来越慢。Redis的长久化过程能够参考:Redis长久化是如何做的?RDB和AOF比照剖析。 而主从复制则是部署多个正本节点,多个正本节点实时复制主节点的数据,当主节点宕机时,咱们有残缺的正本节点能够应用。另一方面,如果咱们业务的读申请量很大,主节点无奈接受所有的读申请,多个正本节点能够分担读申请,实现读写拆散,这样能够进步Redis的拜访性能。 但有个问题是,当主节点宕机时,咱们尽管有残缺的正本节点,但须要手动操作把从节点晋升为主节点持续提供服务,如果每次主节点故障,都须要人工操作,这个过程既耗时耗力,也无奈保障及时性,高可用的水平将大打折扣。如何优化呢? 有了数据长久化、主从复制、故障主动复原这些性能,咱们在应用Redis时是不是就能够居安思危了? 答案是否定的,如果咱们的业务大部分都是读申请,能够应用读写拆散晋升性能。但如果写申请量也很大呢?当初是大数据时代,像阿里、腾讯这些大体量的公司,每时每刻都领有十分大的写入量,此时如果只有一个主节点是无奈接受的,那如何解决呢? 这就须要集群化!简略来说实现形式就是,多个主从节点形成一个集群,每个节点存储一部分数据,这样写申请也能够扩散到多个主节点上,解决写压力大的问题。同时,集群化能够在节点容量有余和性能不够时,动静减少新的节点,对进群进行扩容,晋升性能。 从这篇文章开始,咱们就开始介绍Redis的集群化计划。当然,集群化也意味着Redis部署架构更简单,治理和保护起来老本也更高。而且在应用过程中,也会遇到很多问题,这也衍生出了不同的集群化解决方案,它们的侧重点各不相同。 这篇文章咱们先来整体介绍一下Redis集群化比拟风行的几个解决方案,先对它们有整体的意识,前面我会专门针对我比拟相熟的集群计划进行具体的剖析。 集群化计划要想实现集群化,就必须部署多个主节点,每个主节点还有可能有多个从节点,以这样的部署构造组成的集群,能力更好地承当更大的流量申请和存储更多的数据。 能够承当更大的流量是集群最根底的性能,个别集群化计划还包含了下面提到了数据长久化、数据复制、故障主动复原性能,利用这些技术,来保障集群的高性能和高可用。 另外,优良的集群化计划还实现了在线程度扩容性能,当节点数量不够时,能够动静减少新的节点来晋升整个集群的性能,而且这个过程是在线实现的,业务无感知。 业界支流的Redis集群化计划次要包含以下几个: 客户端分片CodisTwemproxyRedis Cluster它们还能够用是否中心化来划分,其中客户端分片、Redis Cluster属于无中心化的集群计划,Codis、Tweproxy属于中心化的集群计划。 是否中心化是指客户端拜访多个Redis节点时,是间接拜访还是通过一个中间层Proxy来进行操作,间接拜访的就属于无中心化的计划,通过中间层Proxy拜访的就属于中心化的计划,它们有各自的优劣,上面别离来介绍。 客户端分片客户端分片次要是说,咱们只须要部署多个Redis节点,具体如何应用这些节点,次要工作在客户端。 客户端通过固定的Hash算法,针对不同的key计算对应的Hash值,而后对不同的Redis节点进行读写。 客户端分片集群模式客户端分片须要业务开发人员事先评估业务的申请量和数据量,而后让DBA部署足够的节点交给开发人员应用即可。 这个计划的长处是部署十分不便,业务须要多少个节点DBA间接部署交付即可,剩下的事件就须要业务开发人员依据节点数量来编写key的申请路由逻辑,制订一个规定,个别采纳固定的Hash算法,把不同的key写入到不同的节点上,而后再依据这个规定进行数据读取。 可见,它的毛病是业务开发人员应用Redis的老本较高,须要编写路由规定的代码来应用多个节点,而且如果当时对业务的数据量评估不精确,前期的扩容和迁徙老本十分高,因为节点数量产生变更后,Hash算法对应的节点也就不再是之前的节点了。 所以起初又衍生出了一致性哈希算法,就是为了解决当节点数量变更时,尽量减少数据的迁徙和性能问题。 这种客户端分片的计划个别用于业务数据量比较稳定,前期不会有大幅度增长的业务场景下应用,只须要后期评估好业务数据量即可。 Codis随着业务和技术的倒退,人们越发感觉,当我须要应用Redis时,咱们不想关怀集群前面有多少个节点,咱们心愿咱们应用的Redis是一个大集群,当咱们的业务量减少时,这个大集群能够减少新的节点来解决容量不够用和性能问题。 这种形式就是服务端分片计划,客户端不须要关怀集群前面有多少个Redis节点,只须要像应用一个Redis的形式去操作这个集群,这种计划将大大降低开发人员的应用老本,开发人员能够只须要关注业务逻辑即可,不须要关怀Redis的资源问题。 多个节点组成的集群,如何让开发人员像操作一个Redis时那样来应用呢?这就波及到多个节点是如何组织起来提供服务的,个别咱们会在客户端和服务端两头减少一个代理层,客户端只须要操作这个代理层,代理层实现了具体的申请转发规定,而后转发申请到前面的多个节点上,因而这种形式也叫做中心化形式的集群计划,Codis就是以这种形式实现的集群化计划。 Proxy集群模式 Codis架构图 Codis是由国人前豌豆荚大神开发的,采纳中心化形式的集群计划。因为须要代理层Proxy来进行所有申请的转发,所以对Proxy的性能要求很高,Codis采纳Go语言开发,兼容了开发效率和性能。 Codis蕴含了多个组件:codis-proxy:次要负责对申请的读写进行转发codis-dashbaord:对立的控制中心,整合了数据转发规定、故障主动复原、数据在线迁徙、节点扩容缩容、自动化运维API等性能codis-group:基于Redis 3.2.8版本二次开发的Redis Server,减少了异步数据迁徙性能codis-fe:治理多个集群的UI界面可见Codis的组件还是挺多的,它的性能十分全,除了申请转发性能之外,还实现了在线数据迁徙、节点扩容缩容、故障主动复原等性能。 Codis的Proxy就是负责申请转发的组件,它外部保护了申请转发的具体规定,Codis把整个集群划分为1024个槽位,在解决读写申请时,采纳crc32Hash算法计算key的Hash值,而后再依据Hash值对1024个槽位取模,最终找到具体的Redis节点。 Codis最大的特点就是能够在线扩容,在扩容期间不影响客户端的拜访,也就是不须要停机。这对业务应用方是极大的便当,当集群性能不够时,就能够动静减少节点来晋升集群的性能。 为了实现在线扩容,保证数据在迁徙过程中还有牢靠的性能,Codis针对Redis进行了批改,减少了针对异步迁徙数据相干命令,它基于Redis 3.2.8进行开发,下层配合Dashboard和Proxy组件,实现对业务无损的数据迁徙和扩容性能。 因而,要想应用Codis,必须应用它内置的Redis,这也就意味着Codis中的Redis是否能跟上官网最新版的性能个性,可能无奈失去保障,这取决于Codis的保护方,目前Codis曾经不再保护,所以应用Codis时只能应用3.2.8版的Redis,这是一个痛点。 另外,因为集群化都须要部署多个节点,因而操作集群并不能齐全像操作单个Redis一样实现所有性能,次要是对于操作多个节点可能产生问题的命令进行了禁用或限度,具体可参考Codis不反对的命令列表。 但这不影响它是一个优良的集群化计划,因为我司应用Redis集群计划较早,那时Redis Cluster还不够成熟,所以我司应用的Redis集群计划就是Codis。 目前我的工作次要是围绕Codis开展的,咱们公司对Codis进行了定制开发,还对Redis进行了一些革新,让Codis反对了跨多个数据中心的数据同步,因而我对Codis的代码比拟相熟,前面会专门写一些文章来分析Codis的实现原理,学习它的原理,这对咱们了解分布式存储有很大的帮忙! TwemproxyTwemproxy是由Twitter开源的集群化计划,它既能够做Redis Proxy,还能够做Memcached Proxy。 它的性能比拟繁多,只实现了申请路由转发,没有像Codis那么全面有在线扩容的性能,它解决的重点就是把客户端分片的逻辑对立放到了Proxy层而已,其余性能没有做任何解决。 Tweproxy推出的工夫最久,在晚期没有好的服务端分片集群计划时,利用范畴很广,而且性能也极其稳固。 但它的痛点就是无奈在线扩容、缩容,这就导致运维十分不不便,而且也没有敌对的运维UI能够应用。Codis就是因为在这种背景下才衍生进去的。 Redis Cluster采纳两头加一层Proxy的中心化模式时,这就对Proxy的要求很高,因为它一旦呈现故障,那么操作这个Proxy的所有客户端都无奈解决,要想实现Proxy的高可用,还须要另外的机制来实现,例如Keepalive。 而且减少一层Proxy进行转发,必然会有肯定的性能损耗,那么除了客户端分片和下面提到的中心化的计划之外,还有比拟好的解决方案么? Redis官网推出的Redis Cluster另辟蹊径,它没有采纳中心化模式的Proxy计划,而是把申请转发逻辑一部分放在客户端,一部分放在了服务端,它们之间互相配合实现申请的解决。 Redis Cluster是在Redis 3.0推出的,早起的Redis Cluster因为没有通过严格的测试和生产验证,所以并没有宽泛推广开来。也正是在这样的背景下,业界衍生了出了下面所说的中心化集群计划:Codis和Tweproxy。 但随着Redis的版本迭代,Redis官网的Cluster也越来越稳固,更多人开始采纳官网的集群化计划。也正是因为它是官网推出的,所以它的继续维护性能够失去保障,这就比那些第三方的开源计划更有劣势。 Redis Cluster没有了两头的Proxy代理层,那么是如何进行申请的转发呢? Redis把申请转发的逻辑放在了Smart Client中,要想应用Redis Cluster,必须降级Client SDK,这个SDK中内置了申请转发的逻辑,所以业务开发人员同样不须要本人编写转发规定,Redis Cluster采纳16384个槽位进行路由规定的转发。 ...

May 28, 2021 · 1 min · jiezi

关于redis:Redis哨兵模式

主从模式下,slave能够很不便的进行伸缩,但master只有一个,依然存在单点故障问题。明天咱们来看redis的哨兵模式是如何来解决这个问题的。 哨兵职责哨兵模式(sentinel)是redis官网提供的高可用集群解决方案。它是建设在主从模式的根底上,通过哨兵系统监控整个集群的健康状况,对master实例进行主动故障转移。哨兵零碎也是一个高可用的集群零碎,其性能蕴含以下几点 监控(Monitor) 哨兵零碎会不间断(每秒一次的频率)的向监控的redis实例发送ping指令。被监控的redis服务会进行三种回复,PONG、LOADING和MASTERDOWN。如果redis在无效工夫内(down-after-milliseconds设置工夫的大小)进行了PONG的回复,则示意服务运行失常,若未回复,或者回复了其它两种则示意服务异样。告诉(Notification) 当被监控的某个 Redis 服务器呈现问题时, Sentinel 能够通过 API 向管理员或者其余应用程序发送告诉。主动故障迁徙(Automatic failover) sentinel监控到redis服务异样时,并且在指定的时间段内(master-down-after-milliseconds配置)始终是异常情况,sentinel会将该redis服务标记为主观下线(Subjectively Down)。当有足够多的sentinel(通常为一半以上数量的sentinel)都将该redis标记为主观下线时,此时达到了主观下线(Objectively Down)的条件,置为主观下线。sentinel此时会从集群中下掉该redis,同时通过选举选出新的master。应用 replica no one 将slave变为master,而后对其余slave执行 replicaof ip port指定追寻新的master。sentinel也会将本人监控的master配置信息更新掉。哨兵集群启动一个哨兵一个哨兵实例也是一个redis实例,只是运行在非凡的模式下。哨兵默认应用的端口是26379。有两种形式能够启动一个哨兵实例 启动redis-sentinel运行程序启动一个一般的redis程序 redis-server /path/to/sentinel.conf --sentinel配置文件启动 Sentinel 实例必须指定相应的配置文件sentinel.conf, 零碎会应用配置文件来保留 Sentinel 的以后状态, 并在 Sentinel 重启时通过载入配置文件来进行状态还原。因而进行和重启哨兵是平安的,不会产生数据失落。 #监控一个master服务,起个名字叫mymaster,#监控的master的ip:127.0.0.1,端口6379#定义至多要有2个sentinel都批准才能够标记监控redis主观下线sentinel monitor mymaster 127.0.0.1 6379 2#60000毫秒以内监控的redis都没有反馈健康状况,则认为异样sentinel down-after-milliseconds mymaster 60000#主动故障转移的解决过期工夫sentinel failover-timeout mymaster 180000#故障转移实现时可并行同步的slave的实例个数sentinel parallel-syncs mymaster 1哨兵间通信在哨兵集群中,每个哨兵都不须要配置其余哨兵的服务地址,都能够相互交换信息,并监控彼此的可用性。这是借助redis的公布订阅来实现的 哨兵中均指定了监控的master实例,在启动后会在master上开启一个公布订阅信道sentinel_hello所有的哨兵订阅sentinel_hello频道,并向其公布音讯,音讯内容中蕴含了哨兵本人的id、ip和端口哨兵在sentinel_hello中取得其余哨兵的地址信息,更新到本人的哨兵列表中Sentinel 发送的信息中还包含残缺的主服务器以后配置(configuration)。 如果一个 Sentinel 蕴含的主服务器配置比另一个 Sentinel 发送的配置要旧, 那么这个 Sentinel 会立刻降级到新配置上。当咱们开启一个客户端连贯上master redis实例时,能够订阅频道来获取哨兵公布的频道数据 PSUBSCRIBE *

May 27, 2021 · 1 min · jiezi

关于redis:关于如何分析排查解决Redis变慢问题

1、应用简单度过高的命令(例如SORT/SUION/ZUNIONSTORE/KEYS),或一次查问全量数据(例如LRANGE key 0 N,但N很大) 剖析:a) 查看slowlog是否存在这些命令 b) Redis过程CPU使用率是否飙升(聚合运算命令导致) 解决:a) 不应用简单度过高的命令,或用其余形式代替实现(放在客户端做) b) 数据尽量分批查问(LRANGE key 0 N,倡议N<=100,查问全量数据倡议应用HSCAN/SSCAN/ZSCAN) 2、操作bigkey 剖析:a) slowlog呈现很多SET/DELETE变慢命令(bigkey分配内存和开释内存变慢) b) 应用redis-cli -h $host -p $port --bigkeys扫描出很多bigkey 解决:a) 优化业务,防止存储bigkey b) Redis 4.0+可开启lazy-free机制 3、大量key集中过期 剖析:a) 业务应用EXPIREAT/PEXPIREAT命令 b) Redis info中的expired_keys指标短期突增 解决:a) 优化业务,过期减少随机工夫,把工夫打散,加重删除过期key的压力 b) 运维层面,监控expired_keys指标,有短期突增及时报警排查 4、Redis内存达到maxmemory 剖析:a) 实例内存达到maxmemory,且写入量大,淘汰key压力变大 b) Redis info中的evicted_keys指标短期突增 解决:a) 业务层面,依据状况调整淘汰策略(随机比LRU快) b) 运维层面,监控evicted_keys指标,有短期突增及时报警 c) 集群扩容,多个实例加重淘汰key的压力 5、大量短连贯申请 剖析:Redis解决大量短连贯申请,TCP三次握手和四次挥手也会减少耗时 解决:应用长连贯操作Redis 6、生成RDB和AOF重写fork耗时重大 剖析:a) Redis变慢只产生在生成RDB和AOF重写期间 b) 实例占用内存越大,fork拷贝内存页表越久 c) Redis info中latest_fork_usec耗时变长 解决:a) 实例尽量小 b) Redis尽量部署在物理机上 c) 优化备份策略(例如低峰期备份) d) 合理配置repl-backlog和slave client-output-buffer-limit,防止主从全量同步 e) 视状况思考敞开AOF f) 监控latest_fork_usec耗时是否变长 ...

May 27, 2021 · 1 min · jiezi

关于redis:图解-Redis-不就是-AOF-持久化嘛

AOF 日志试想一下,如果 Redis 每执行一条写操作命令,就把该命令以追加的形式写入到一个文件里,而后重启 Redis 的时候,先去读取这个文件里的命令,并且执行它,这不就相当于复原了缓存数据了吗? 这种保留写操作命令到日志的长久化形式,就是 Redis 里的 AOF(Append Only File) 长久化性能,留神只会记录写操作命令,读操作命令是不会被记录的,因为没意义。 在 Redis 中 AOF 长久化性能默认是不开启的,须要咱们批改 redis.conf 配置文件中的以下参数: AOF 日志文件其实就是一般的文本,咱们能够通过 cat 命令查看外面的内容,不过外面的内容如果不晓得肯定的规定的话,可能会看不懂。 我这里以「set name xiaolin」命令作为例子,Redis 执行了这条命令后,记录在 AOF 日志里的内容如下图: 我这里给大家解释下。 「*3」示意以后命令有三个局部,每局部都是以「$+数字」结尾,前面紧跟着具体的命令、键或值。而后,这里的「数字」示意这部分中的命令、键或值一共有多少字节。例如,「$3 set」示意这部分有 3 个字节,也就是「set」命令这个字符串的长度。 不晓得大家留神到没有,Redis 是先执行写操作命令后,才将该命令记录到 AOF 日志里的,这么做其实有两个益处。 第一个益处,防止额定的查看开销。 因为如果先将写操作命令记录到 AOF 日志里,再执行该命令的话,如果以后的命令语法有问题,那么如果不进行命令语法查看,该谬误的命令记录到 AOF 日志里后,Redis 在应用日志复原数据时,就可能会出错。 而如果先执行写操作命令再记录日志的话,只有在该命令执行胜利后,才将命令记录到 AOF 日志里,这样就不必额定的查看开销,保障记录在 AOF 日志里的命令都是可执行并且正确的。 第二个益处,不会阻塞以后写操作命令的执行,因为当写操作命令执行胜利后,才会将命令记录到 AOF 日志。 当然,AOF 长久化性能也不是没有潜在危险。 第一个危险,执行写操作命令和记录日志是两个过程,那当 Redis 在还没来得及将命令写入到硬盘时,服务器产生宕机了,这个数据就会有失落的危险。 第二个危险,后面说道,因为写操作命令执行胜利后才记录到 AOF 日志,所以不会阻塞以后写操作命令的执行,然而可能会给「下一个」命令带来阻塞危险。 因为将命令写入到日志的这个操作也是在主过程实现的(执行命令也是在主过程),也就是说这两个操作是同步的。 如果在将日志内容写入到硬盘时,服务器的硬盘的 I/O 压力太大,就会导致写硬盘的速度很慢,进而阻塞住了,也就会导致后续的命令无奈执行。 ...

May 27, 2021 · 2 min · jiezi

关于redis:使用-Redis-实现一个轻量级的搜索引擎牛x啊

场景 大家如果是做后端开发的,想必都实现过列表查问的接口,当然有的查问条件很简略,一条 SQL 就搞定了,但有的查问条件极其简单,再加上库表中设计的各种不合理,导致查问接口特地难写,而后加班什么的就不用说了(不知各位有没有这种感触呢~)。 上面以一个例子开始,这是某购物网站的搜寻条件,如果让你实现这样的一个搜寻接口,你会如何实现?(当然你说借助搜索引擎,像 Elasticsearch 之类的,你齐全能够实现。但我这里想说的是,如果要你本人实现呢?)从上图中能够看出,搜寻总共分为6大类,每大类中又分了各个子类。这两头,各大类条件之间是取的交加,各子类中有单选、多选、以及自定义的状况,最终输入符合条件的后果集。 好了,既然需要很明确了,咱们就开始来实现。 实现1 率先退场是小A同学,他是写 SQL 方面的“专家”。小A信念满满的说:“不就是一个查问接口吗?看着条件很多,但凭着我丰盛的 SQL 教训,这点还是难不倒我的。” 于是乎就写出了上面这段代码(这里以 MYSQL 为例): select ... from table_1left join table_2left join table_3left join (select ... from table_x where ...) tmp_1...where ...order by ...limit m,n代码在测试环境跑了一把,后果如同都匹配上了,于是筹备上预发。这一上预发,问题就开始裸露进去。预发为了尽可能的真切线上环境,所以数据量自然而然要比测试大的多。所以这么一个简单的 SQL,它的执行效率可想而知。测试同学果决把小A的代码给打了回来。 实现2 总结了小A失败的教训,小B开始对SQL进行了优化,先是通过了explain关键字进行SQL性能剖析,对该加索引的中央都加上了索引。同时将一条简单SQL拆分成了多条SQL,计算结果在程序内存中进行计算。 伪代码如下: $result_1 = query('select ... from table_1 where ...');$result_2 = query('select ... from table_2 where ...');$result_3 = query('select ... from table_3 where ...');...$result = array_intersect($result_1, $result_2, $result_3, ...);这种计划从性能上显著比第一种要好很多,可是在性能验收的时候,产品经理还是感觉查问速度不够快。小B本人也晓得,每次查问都会向数据库查问屡次,而且有些历史起因,局部条件是做不到单表查问的,所以查问期待的工夫是防止不了的。 实现3 ...

May 25, 2021 · 1 min · jiezi

关于redis:P8架构师详解Redis-在-MySql-中的优化历程

本文章转自:乐字节 文章次要解说:Redis 在 MySql 中的优化历程 获取更多Java相干常识能够关注公众号《乐字节》 发送:999 我是Redis你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上。 说起我的诞生,跟关系数据库MySQL还挺有渊源的。在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网倒退的越来越快,它包容的数据也越来越多,用户申请也随之暴涨,而每一个用户申请都变成了对它的一个又一个读写操作,MySQL是苦不堪言。尤其是到“双11”、“618“这种全民购物狂欢的日子,都是MySQL受苦受难的日子。据起初MySQL通知我说,其实有一大半的用户申请都是读操作,而且常常都是反复查问一个货色,节约它很多工夫去进行磁盘I/O。起初有人就推敲,是不是能够学学CPU,给数据库也加一个缓存呢?于是我就诞生了!出世不久,我就和MySQL成为了好敌人,咱们俩经常携手呈现在后端服务器中。应用程序们从MySQL查问到的数据,在我这里注销一下,前面再须要用到的时候,就先找我要,我这里没有再找MySQL要。 因为我把注销的数据都记录在内存中,不必去执行慢如蜗牛的I/O操作,所以找我要比找MySQL要省去了不少的工夫呢。可别小瞧这简略的一个扭转,我可为MySQL加重了不小的累赘!随着程序的运行,我缓存的数据越来越多,有相当局部工夫我都给它挡住了用户申请,这一下它可乐得清闲自在了!有了我的退出,网络服务的性能晋升了不少,这都归功于我为数据库挨了不少枪子儿。 缓存过期 && 缓存淘汰不过很快我发现事件不妙了,我缓存的数据都是在内存中,可是就算是在服务器上,内存的空间资源还是很无限的,不能无节制的这么存上来,我得想个办法,不然吃枣药丸。不久,我想到了一个方法:给缓存内容设置一个超时工夫,具体设置多长交给应用程序们去设置,我要做的就是把过期了的内容从我外面删除掉,及时腾出空间就行了。 超时工夫有了,我该在什么时候去干这个清理的活呢?最简略的就是定期删除,我决定100ms就做一次,一秒钟就是10次!我清理的时候也不能一口气把所有过期的都给删除掉,我这外面存了大量的数据,要全面扫一遍的话那不晓得要花多久工夫,会重大影响我接待新的客户申请的!工夫紧工作重,我只好随机抉择一部分来清理,能缓解内存压力就行了。 就这样过了一段日子,我发现有些个键值运气比拟好,每次都没有被我的随机算法选中,每次都能幸免于难,这可不行,这些长时间过期的数据始终霸占着不少的内存空间!气抖冷!我眼里可揉不得沙子!于是在原来定期删除的根底上,又加了一招:那些原来逃脱我随机抉择算法的键值,一旦遇到查问申请,被我发现曾经超期了,那我就绝不客气,立刻删除。这种形式因为是被动式触发的,不查问就不会产生,所以也叫惰性删除!可是,还是有局部键值,既逃脱了我的随机抉择算法,又始终没有被查问,导致它们始终绳之以法!而于此同时,能够应用的内存空间却越来越少。 而且就算退一步讲,我可能把过期的数据都删除掉,那万一过期工夫设置的很长,还没等到我去清理,内存就吃满了,一样要吃枣药丸,所以我还得想个办法。我苦思好久,终于憋出了个大招:内存淘汰策略,这一次我要彻底解决问题!我提供了8种策略供应用程序抉择,用于我遇到内存不足时该如何决策: 有了下面几套组合拳,我再也不必放心过期数据多了把空间撑满的问题了~ 缓存穿透 && 布隆过滤器我的日子过的还挺舒坦,不过MySQL大哥就没我这么舒坦了,有时候遇到些烦人的申请,查问的数据不存在,MySQL就要白忙活一场!不仅如此,因为不存在,我也没法缓存啊,导致同样的申请来了每次都要去让MySQL白忙活一场。我作为缓存的价值就没失去体现啦!这就是人们常说的缓存穿透。 这一来二去,MySQL大哥忍不住了:“唉,兄弟,能不能帮忙想个办法,把那些明晓得不会有后果的查问申请给我挡一下”这时我想到了我的另外一个好敌人:布隆过滤器。 我这位敌人别的本事没有,就善于从超大的数据集中疾速通知你查找的数据存不存在(轻轻通知你,我的这位敌人有一点不靠谱,它通知你存在的话不能全信,其实有可能是不存在的,不过它他要是通知你不存在的话,那就肯定不存在)。 如果你对我这位敌人感兴趣的话,能够看看这里《文言布隆过滤器BloomFilter》。我把这位敌人介绍给了应用程序,不存在的数据就不用去叨扰MySQL了,轻松帮忙解决了缓存穿透的问题。 缓存击穿 && 缓存雪崩这之后过了一段时间太平日子,直到那一天···有一次,MySQL那家伙正优哉游哉的摸鱼,忽然一大堆申请给他怼了过来,给他打了一个措手不及。一阵忙活之后,MySQL火冒三丈的找到了我,“兄弟,咋回事啊,怎么一下子来的这么猛” 我查看了日志,连忙解释到:“大哥,切实不好意思,刚刚有一个热点数据到了过期工夫,被我删掉了,不巧的是随后就有对这个数据的大量查问申请来了,我这里曾经删了,所以申请都发到你那里来了”“你这干的叫啥事,下次留神点啊”,MySQL大哥一脸不快乐的来到了。这一件小事我也没怎么放在心上,随后就抛之脑后了,却没曾想几天之后竟捅了更大的篓子。那一天,又呈现了大量的网络申请发到了MySQL那边,比上一次的规模大得多,MySQL大哥一会儿功夫就给干趴下了好几次!等了好半天这一波流量才算过来,MySQL才缓过神来。“老弟,这一次又是什么起因?”,MySQL大哥累的没了力量。“这一次比上一次更不巧,这一次是一大批数据简直同时过了有效期,而后又产生了很多对这些数据的申请,所以比起上一次这规模更大了” MySQL大哥听了眉头一皱,“那你倒是想个办法啊,三天两头折磨我,这谁顶得住啊?”“其实我也很无奈,这个工夫也不是我设置的,要不我去找应用程序说说,让他把缓存过期工夫设置的平均一些?至多别让大量数据个体生效”“走,咱俩一起去”起初,我俩去找应用程序磋商了,不仅把键值的过期工夫随机了一下,还设置了热点数据永不过期,这个问题缓解了不少。哦对了,咱们还把这两次产生的问题别离取了个名字:缓存击穿和缓存雪崩。咱们终于又过上了舒服的日子··· 感激大家的认同与反对,小编会继续转发《乐字节》优质文章

May 24, 2021 · 1 min · jiezi

关于redis:Ubuntu20-WSL-安装Redis-报错Connection-refused

原本想在windows上装置一个Redis,然而发现官网都没有提供预编译好的二进制发行版本,这就很让人头疼了。那就想着在WSL上装置吧,美滋滋。在Ubuntu20.04 WSL上装置redis有两种形式: 应用apt包管理器自行编译源代码先说第一种方法,通过apt包管理器装置Redis是最不便的只需如下两行命令即可 sudo apt updatesudo apt install redis-server然而实际上不行,你会发现一些谬误: csy@Yoga14S-yjc:~$ systemctl status redis-serverSystem has not been booted with systemd as init system (PID 1). Can't operate.Failed to connect to bus: Host is down以及 csy@Yoga14S-yjc:~$ redis-cliCould not connect to Redis at 127.0.0.1:6379: Connection refusednot connected>not connected>not connected>not connected>not connected>not connected> dsaCould not connect to Redis at 127.0.0.1:6379: Connection refusednot connected>这就很麻烦,为了解决Connection refused谬误能够执行一下命令 sudo service redis-server start这是便能够失常应用redis-cli了 csy@Yoga14S-yjc:~$ redis-cli127.0.0.1:6379> exit然而输出systemctl status redis-server查看redis-server的运行状态还是不行然而通过service命令是能够的。 ...

May 24, 2021 · 1 min · jiezi

关于redis:redis随笔

混合模式把 aof-use-rdb-preamble 配成 yes就行了前半部分为rdb,后半部分为aof 执行完BGREWRITEAOFaof日志:rdb、aof日志混存,为追加形式 redis-cli info replication查看主从日志 # Replicationrole:masterconnected_slaves:2slave0:ip=127.0.0.1,port=6377,state=online,offset=1193,lag=1slave1:ip=127.0.0.1,port=6378,state=online,offset=1193,lag=1master_replid:32da60ea7925c076cd058b41768e7cac9a0cfdc5master_replid2:0000000000000000000000000000000000000000master_repl_offset:1193second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:1193获取redis主从同步信息,应用的是laravel框架Redis::info('REPLICATION') array ( 'role' => 'master', 'connected_slaves' => 2, 'slave0' => 'ip=127.0.0.1,port=6377,state=online,offset=6569,lag=1', 'slave1' => 'ip=127.0.0.1,port=6378,state=online,offset=6569,lag=1', 'master_replid' => '32da60ea7925c076cd058b41768e7cac9a0cfdc5', 'master_replid2' => 0, 'master_repl_offset' => 6569, 'second_repl_offset' => -1, 'repl_backlog_active' => 1, 'repl_backlog_size' => 1048576, 'repl_backlog_first_byte_offset' => 1, 'repl_backlog_histlen' => 6569,)集群相干配置 sentinel.conf 文件配置规定工夫内不能再次链接不能作为主库sentinel down-after-milliseconds <master-name> <milliseconds>down-after-milliseconds * 10选举规定1、配置权重:redis.conf中 slave-priority 权重 配置2、1雷同,进行offset匹配,应用最新靠近的offset,offset能够通过info replication 看到,主库执行看到的是offset,从库执行看到的是 slave_repl_offset 127.0.0.1:6377> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:8501slave_priority:100slave_read_only:1connected_slaves:0master_replid:32da60ea7925c076cd058b41768e7cac9a0cfdc5master_replid2:0000000000000000000000000000000000000000master_repl_offset:8501second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:85013、ID 号小的从库得分高:run_id 应用info server获取 127.0.0.1:6377> info server# Serverredis_version:6.0.8redis_git_sha1:00000000redis_git_dirty:0redis_build_id:e03d903ddcb7b789redis_mode:standaloneos:Linux 3.10.0-1160.24.1.el7.x86_64 x86_64arch_bits:64multiplexing_api:epollatomicvar_api:atomic-builtingcc_version:9.3.1process_id:17897run_id:dded9b69f5510f7cdd21b9b67f3c7ac46bd249bbtcp_port:6377uptime_in_seconds:23168uptime_in_days:0hz:10configured_hz:10lru_clock:10634004executable:/root/redis-serverconfig_file:/etc/redis/redis6377.confio_threads_active:0redis 分片hash槽量:16383,获取失败会返回move谬误或ask谬误 ...

May 24, 2021 · 2 min · jiezi

关于redis:公共redis工具类提取

Redis的键值默认应用JDK序列化,为不便排查问题,需自定义Json列化,并退出客户端操作工具类,不便各服务应用。 1、定义序列化FastJsonRedisSerializer public class FastJsonRedisSerializer<T> implements RedisSerializer<T> { public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; private Class<T> clazz; public FastJsonRedisSerializer(Class<T> clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { if (t == null) { return new byte[0]; } return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length <= 0) { return null; } String str = new String(bytes, DEFAULT_CHARSET); return (T) JSON.parseObject(str, clazz); }}2、自定义redisTemplate ...

May 24, 2021 · 14 min · jiezi

关于redis:Redis-客户端

Redis 客户端1、redis 为每个客户端保留的状态信息:(01)客户端的套接字描述符(02)客户端的名字(03)客户端的标记值(flag)(05)指向客户端正在应用的数据库指针,以及该数据库的号码(06)客户端以后要执行的命令、命令的参数、命令参数的个数,以及指向命令实现函数的指针。(07)客户端的输出缓冲区和输入缓冲区。(08)客户端的复制状态信息,以及进行复制所需的数据结构。(09)客户端执行BRPOP、BLPOP等列表阻塞命令时应用的数据结构。(10)客户端的事务状态,以及执行WATCH命令时用到的数据结构。(11)客户端执行公布与订阅性能时用到的数据结构。(12)客户端的身份验证标记。(13)客户端的创立工夫,客户端和服务器最初一次通信的工夫,以及客户端的输入缓冲区大小超出软性限度(soft limit)的工夫。2、客户端属性:2、1:fd属性记录了客户端正在应用的套接字描述符 (1)-1:伪客户端的fd属性值 (2)大于-1:一般客户端的fd属性值2、2: 客户端的名字 (1)客户端的名字记录在客户端状态的name属性里 (2)name默认空白,CLIENT set命令设置名称2、3: 标记,flag (1)记录客户端的角色,以及客户端状态。REDIS_MASTER:主服务器;REDIS_SLAVE:从服务器;REDIS_PRE_PSYNC:低于redis2.8的从服务器;REDIS_LUA_CLIENT:lua命令伪客户端;REDIDS_MONITOR:正在执行monitor命令;REDIS_UNIX_SOCKET:UINIX套接字客户端2、4:输出缓冲区 querybuf属性保留客户端命令,最大1GB2、5:命令与命令参数 命令参数以及命令参数的个数别离保留在argv(数组)和argc(数组长度)中2、6:命令函数的实现 (1)argv[0]对应命令表中的命令实现函数 (2)命令表是个字典构造,字典的键是SDS构造,字典的值是redisCommand构造2、7:输入缓冲区 (1)保留命令回复 (2)固定大小的缓冲区保留长度比拟小的回复,可变大小的缓冲区保留长度比拟大的回复2、8:身份验证 客户端状态的authenticated属性用于记录客户端是否通过了身份验证,0/1别离记录是否通过了身份验证2、9: 工夫 (1)ctime:客户端创立工夫 (2)lastinteraction:客户端与服务器上次产生交互的工夫 (3)obuf_soft_limit_recached_time:记录了输入缓冲区第一次达到soft limit的工夫3、客户端的创立与敞开3、1:创立一般客户端 增加一个client到clients表的开端3、2: 敞开一般客户端 (1)客户端过程退出或被杀死 (2)发送带有不合协定格局的命令 (3)客户端成为CLIENT KILL命令的指标 (4)设置了timeout配置选项且到了设置的值 (5)命令大小超过了命令缓冲区的限度大小 (6)命令回复超过了输入缓冲区的大小3、3: lua脚本伪客户端 服务器初始化时创立,服务器容许期间始终在3、4: AOF文件的伪客户端 服务器在载入AOF文件时创立,载入结束敞开

May 23, 2021 · 1 min · jiezi

关于redis:Redis持久化AOF

AOF(append of only)相似于MySQL的binlog,是将redis操作的指令做为日志保留到文件中,做为数据的备份。应用该文件能够重放所有时刻的内存数据,当然也能够复原到最新的数据状态。AOF保留的默认文件名为dump.aof,能够通过配置批改文件名称 appendfilename appendonly.4379.aofRedis的默认状态是敞开AOF的长久化性能的,应用配置开启 appendonly yes在AOF性能开启后,Redis启动时会优先应用aof文件复原内存,这是因为AOF的数据绝对于RDB数据保留的更残缺一些,这个咱们前面会详情介绍。 AOF长久化实现Redis在执行完写命令时,会将执行命令以一种协定的形式写入到aof文件中。Redis对命令的长久化提供了三种模式:AOF_FSYNC_NO、AOF_FSYNC_EVERYSEC和 AOF_FSYNC_ALWAYS。Redis在写文件的时候,操作系统内核会开启一个缓冲区buffer,文件写入缓存区,当缓冲区已满时,操作系统会刷新buffer真正的写入到磁盘。程序也能够强制刷新缓冲区来将数据刷到磁盘上。依据这个机制,咱们看一下Redis的三种长久化模式的区别。 AOF_FSYNC_ALWAYS 每接管一个写操作都进行一次长久化,即先执行write()函数,写入操作系统的缓冲区,而后再调用fsync将数据同步到磁盘上。Always模式尽管保障了数据的安全性,但频繁的IO也会减少磁盘的压力,从而升高Redis的整体效率。AOF_FSYNC_NO Redis不会被动进行fsync操作,只会将数据写入到缓冲区,由操作系统来管制是否写入磁盘。刷盘的操作在以下三种状况下会被触发: AOF性能被敞开 Redis服务敞开 超过30秒(操作系统默认是30秒刷新一次缓存区)或操作系统缓冲区已满这种形式升高了IO频繁刷盘的压力,但数据安全性上会存在一些问题,服务宕机时有可能造成一个缓冲区大小的数据失落。AOF_FSYNC_EVERYSEC 联合下面两种模式做了折中,每秒都会进行一次刷盘的操作,从数据安全性上和IO压力上进行了均衡。Redis主过程会调用fork()函数生成一个子过程,用于aof文件的存盘解决。子过程会每隔一秒钟执行一次fsync同步文件到磁盘,在执行fsync时,存在三种状况如果子过程正在进行save磁盘操作,且执行工夫小于2秒钟时,flushAppendOnlyFile会立刻返回;当子过程执行save的工夫超过2秒钟时,则只会执行写入缓冲区操作。但此时写入缓冲区依然会阻塞期待之前的save执行结束能力进行,而后接着执行新的save操作;以后子过程没有执行SAVE操作,此时须要看间隔最近一次save胜利的工夫距离,如果大于1秒,则间接执行write,并执行save。小于1秒时则只进行write操作。从下面的过程来看Redis失落的数据有可能在2秒以上。EVERYSEC模式兼顾了安全性和性能,适应大多数的利用场景,生产上个别也会应用这种模式。appendfsync everysec#appendfsync aways#appendfsync noAOF文件重写随着Redis运行工夫的减少,aof文件会变的越来越大,redis提供了从新的性能来防止文件过大而产生性能问题。AOF重写时也利用的写时复制机制, 调用fork()函数取得一个子过程,并和父过程共享内存数据子过程将内存数据转化成对应的命令协定数据,写入长期aof文件;同时父过程会开拓一块内存缓存区,接管新的写操作。在此过程中父过程仍然会向现有的aof文件追加操作指令,以保障以后的aof文件可用性子过程重写结束后,父过程会失去一个信号,将重写过程中接管到的写入操作追加到长期aof文件开端将aof文件切换到新的文件上在redis4.0版本之后,反对采纳RDB和AOF的混合模式进行重写。Redis先将内存数据已RDB的形式写入到AOF文件中,而后再将新增的写操作命令追加到文件开端。在redis进行内存加载时,当读取到文件以REDIS为结尾的数据时,就做为RDB的模式进行内存复原,而后对前面增量的AOF命令数据进行执行即可。这样即利用了RDB占用空间小和复原快的长处,还兼顾AOF数据存储实时的个性。配置文件中这样开启 aof-use-rdb-preamble yesAOF重写触发机制redis中提供了BGREWRITEAOF命令来手动执行aof的重写。在配置文件能够通过如下配置来管制主动触发 auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbRedis每次rewrite之后会记录下来aof文件的大小,当aof文件大小大于64M并且超过了上次重写完的文件大小值的100%时,主动进行一次rewrite操作。

May 23, 2021 · 1 min · jiezi

关于redis:REDIS文件事件

REDIS事件处理零碎,基于reactor模式开发。socket代表与客户端或其它服务器之间的连贯。当socket可交互时,即产生相应的文件事件,服务器监听并解决这些事件,来实现相应操作。 多个事件会并发呈现。I/O多路复用程序,将事件放到队列里,并以有序、同步、每次一个的形式,向事件散发器传送。事件散发器将事件交给对应的事件处理器已解决工作。 I/O多路复用REDIS为不同的I/O多路复用函数库,实现了雷同的API,底层实现能够是select、epoll、evport、kqueue,程序在编译时,抉择性能最高的函数库。相似于java的接口与实现。 扩大:什么是I/O多路复用? 事件类型和处理器redis蕴含两个事件类型:ae.h/AE_READABLE、ae.h/AE_WRITEABLE 客户端动作事件处理器connectAE_READABLE(serverFd)连贯应答处理器writeAE_READABLE命令申请处理器readAE_WRITEABLE命令回复处理器closeAE_READABLE连贯断开处理器连贯应答处理器networking.c/acceptTcpHandler 监听:服务器启动时,建设监听套接字的AE_READABLE事件和连贯应答处理器的绑定关系;触发:当客户端连贯到服务器监听套接字的时候,监听套接字产生AE_READABLE事件,触发连贯应答处理器,执行客户端连贯操作。 命令申请处理器networking.c/readQueryFromClient 监听:客户端连贯时,连贯应答处理器,建设客户端套接字的AE_READABLE事件和命令申请处理器的绑定关系;触发:当客户端发送命令时,触发AE_READABLE事件,命令申请处理器执行命令读入和解决。 命令回复处理器networking.c/sendReplyToClient 监听:命令申请处理器执行实现后,将须要回复的音讯存在客户端reply缓存内,并监听AE_WRITEABLE事件触发:当客户端read时,命令回复处理器将reply缓存内的音讯写入客户端socket。而后勾销AE_WRITEABLE关联 参考【1】《Redis 设计与实现》【2】redis事件循环

May 22, 2021 · 1 min · jiezi

关于redis:Redis的RDB方式

明天咱们来聊一聊Redis长久化的形式RDB。 咱们晓得Redis绝对于传统的缓存技术最大的特点之一就是反对数据的长久化。Redis会定期对内存数据快照写入磁盘,当内存数据失落(如服务重启、宕机导致)时,能够加载磁盘中的数据疾速复原到内存。 RDB即Redis Database,其长久化形式是将内存数据以二进制的形式存储到磁盘上,防止服务器意外宕机时依然能够从磁盘找回数据。存储的文件默认为dump.rdb。 RDB长久化操作过程 Redis fork一个子过程子过程领有主过程的内存数据正本,子过程将内存正本数据写入长期的rdb文件中子过程写入实现后,用新的rdb文件替换掉原有的rdb文件,同时删除旧的文件其实子过程被fork进去后,会同时拷贝一份主过程的内存援用,而非残缺的内存正本集。这就利用了操作的零碎的写时复制性能,只有在父过程的内存产生批改时才会实在的复制一份内存给子过程应用,而且复制是以页为单位进行的。这样就大大减少了内存的应用空间,晋升了效率。整个长久化过程中只有fork过程会发送阻塞,子过程rdb文件的存储过程是异步的。 RDB是如何触发的Redis提供命令来手动触发rdb操作:save和bgsave。两者的区别是save是同步操作,执行过程中会阻塞Redis对外服务。尤其在大数据量的save时,会导致服务较长时间的服务中断。而bgsave则是fork一个子过程来异步解决长久化,长久化的过程齐全不影响Redis服务,生产上也是罕用。 Redis提供了参数来配置RDB的主动触发,定义 m秒内n次键值产生改变。例如 save 900 1save 300 10save 60 1000060秒内呈现10000次键值变更300秒内呈现10次键值扭转900秒内1次键值扭转示意当满足上述三种状况的任一种时,都将触发一次bgsave操作。 另外有一点补充阐明一下,在执行save或bgsave操作时,如果发现零碎有正在执行的save操作,而且未超过2秒 主动存储的实现细节redisServer保护了主动触发的配置信息,同时保护了一个dirty计数器和上次执行完save的工夫。 struct redisServer { // 主动保留的配置信息 struct saveparam *saveparams; long dirty;//批改计数器 time_t lastsave;//上一次执行save的工夫 // ...};struct saveparam { time_t seconds;//秒数 int changes;//批改次数};dirty计数器 redis每执行一次写入操作时,dirty值+1,lastsave 记录最近一次胜利执行完save/bgsave操作的工夫(Unix工夫戳)serverCron是redis中的周期执行函数,默认100ms执行一次(可通过redis.config批改执行频率),其中一个查看就是查看是否满足了RDB主动执行条件。对于单个 save m n来说,只有当同时满足以下两个条件时,才会触发一次长久化 now - lastsave > mdirty >= n这里的n次变更是指服务端的变更,而不是执行客户端申请的写入命令操作数。即,当执行一条 sadd myset a b c, dirty的值会减少3。 RDB相干的配置 save m n m秒内产生n次变更则执行一次bgsave。呈现save配置后,redis会启用rdb长久化dir /usr/local/redis-5.0.7/data 快照文件门路dbfilename dump.rdb 快照文件名,默认为dump.rdb。生产环境个别会退出端口信息,命名为:dupm.6379.rdbstop-writes-on-bgsave-error yes 当bgsave执行出现异常时,是否进行接管客户端的写入申请。rdbcompression yes 启用rdb文件压缩。启用压缩后会节俭磁盘空间,但减少CPU的耗费资源rdbchecksum yes 启用rdb文件一致性校验应用RDB复原数据 ...

May 18, 2021 · 1 min · jiezi

关于redis:Redis-事件

Redis 事件1、两类事件:1、1: 文件事件(file event)1、2: 工夫事件(time event)2、文件事件:2、1: 原理:Redis服务器通过套接字与其余(客户端或其余Redis服务器)进行链接,通信时产生相应的文件事件,而服务器通过监听和解决这些事件来实现一系列网络通信操作。2、2: 重要要害思路:文件事件通过应用I/O多路复用程序监听多个socket。(Redis单线程 但高性能的重要起因)2、3: 与socket操作相干的事件产生时,文件事件处理器就会调用关联好的事件处理器来解决这些事件。2、4: 文件事件的组成:socket、I/O多路复用、文件事件分派器、事件处理器2、5:事件类型:可读事件、可写事件(优先读事件)3、文件事件处理器3、1: 连贯应答处理器(acceptTcpHandler)3、2: 命令申请处理器(readQueryFromClient)3、3: 命令回复处理器(sendReplyToCLient)一次残缺的客户端与服务器连贯事件:(1)客户端向服务器发送连贯申请,服务器执行连贯应答处理器(2)客户端向服务器发送命令申请,服务器执行命令申请处理器(3)服务器向客户端发送命令回复,服务器执行命令回复处理器4、工夫事件4、1: 工夫事件分类 (1)定时事件 (2)周期性事件4、2: 工夫事件的组成 (1)ID:惟一标识,程序递增 (2)when:毫秒unix工夫戳,记录时间事件的达到工夫 (3)timeProc:事件处理器函数4、3: 定时事件和周期性事件的辨别: 按返回值辨别,返回ae.h/AE_NOMORE为定时事件,返回非AE_NOMORE的整数为周期事件。 注:返回整数则对事件的when属性进行更新5、事件事件的实现5、1: 所有的工夫事件都放在一个无序链表,每当工夫事件执行器执行需遍历整个链表(性能?)注:按ID排序放,非按when属性排序放5、2:性能问题解答:在目前版本中,失常模式下的 Redis服务器只应用servercron一个工夫事件,而在benchmark模式下,服务器也只应用两个工夫事件。在这种状况下,服务器简直是将无序链表进化成一个指针来应用,所以应用无序链表来保留工夫事件,并不影响事件执行的性能。6、工夫工夫实例:serverCron函数的作用(1)更新服务器各类统计信息(2)清理数据库中的过期键值对(3)敞开和清理连贯生效的客户端(4)AOF 和 RDB长久化操作(5)主从服务器数据同步(6)集群模式下进行定期同步和连贯测试

May 17, 2021 · 1 min · jiezi

关于redis:Redis-缓存的三大问题及其解决方案

Redis常常用于零碎中的缓存(MySQL 与 Redis 缓存的同步计划),这样能够解决目前IO设施无奈满足互联网利用海量的读写申请的问题。 一、缓存穿透缓存穿透是指缓存和数据库中都没有的数据,而用户一直发动申请,如发动id为-1的数据或者特地大的不存在的数据。有可能是黑客利用破绽攻打从而去压垮利用的数据库。 1. 常见解决方案对于缓存穿透问题,常见的解决方案有以下三种: 验证拦挡:接口层进行校验,如鉴定用户权限,对ID之类的字段做根底的校验,如id<=0的字段间接拦挡;缓存空数据:当数据库查问到的数据为空时,也将这条数据进行缓存,但缓存的有效性设置得要较短,免得影响失常数据的缓存;public Student getStudentsByID(Long id) { // 从Redis中获取学生信息 Student student = redisTemplate.opsForValue() .get(String.valueOf(id)); if (student != null) { return student; } // 从数据库查问学生信息,并存入Redis student = studentDao.selectByStudentId(id); if (student != null) { redisTemplate.opsForValue() .set(String.valueOf(id), student, 60, TimeUnit.MINUTES); } else { // 即便不存在,也将其存入缓存中 redisTemplate.opsForValue() .set(String.valueOf(id), null, 60, TimeUnit.SECONDS); } return student;}应用布隆过滤器:布隆过滤器是一种比拟独特数据结构,有肯定的误差。当它指定一个数据存在时,它不肯定存在,然而当它指定一个数据不存在时,那么它肯定是不存在的。2. 布隆过滤器布隆过滤器是一种比拟非凡的数据结构,有点相似与HashMap,在业务中咱们可能会通过应用HashMap来判断一个值是否存在,它能够在O(1)工夫复杂度内返回后果,效率极高,然而受限于存储容量,如果可能须要去判断的值超过亿级别,那么HashMap所占的内存就很可观了。 而BloomFilter解决这个问题的计划很简略。首先用多个bit位去代替HashMap中的数组,这样的话贮存空间就下来了,之后就是对 Key 进行屡次哈希,将 Key 哈希后的值所对应的 bit 地位为1。 当判断一个元素是否存在时,就去判断这个值哈希进去的比特位是否都为1,如果都为1,那么可能存在,也可能不存在(如下图F)。然而如果有一个bit位不为1,那么这个Key就必定不存在。 留神:BloomFilter并不反对删除操作,只反对增加操作。这一点很容易了解,因为你如果要删除数据,就得将对应的bit地位为0,然而你这个Key对应的bit位可能其余的Key也对应着。 3. 缓存空数据与布隆过滤器的比拟上面对这两种计划都进行了简略的介绍,缓存空数据与布隆过滤器都能无效解决缓存穿透问题,但应用场景有着些许不同; 当一些歹意攻打查问查问的key各不相同,而且数量巨多,此时缓存空数据不是一个好的解决方案。因为它须要存储所有的Key,内存空间占用高。并且在这种状况下,很多key可能只用一次,所以存储下来没有意义。所以对于这种状况而言,应用布隆过滤器是个不错的抉择;而对与空数据的Key数量无限、Key反复申请效率较高的场景而言,能够抉择缓存空数据的计划。二、缓存击穿缓存击穿是指以后热点数据存储到期时,多个线程同时并发拜访热点数据。因为缓存刚过期,所有并发申请都会到数据库中查问数据。 ...

May 17, 2021 · 1 min · jiezi

关于redis:Redis入门指南第-2-版读后感

一本合格的 Redis 入门书李子骅所作的《Redis入门指南(第 2 版)》是一本合格的 Redis 入门书,依据豆瓣的评分规定,我给这本书的豆瓣评分是 4 星。当然,这个评分是针对“入门”这个档次而言的。 这是一本 Redis 入门指导书。尽管本书在内容摘要写道: 本书的指标读者不仅包含 Redis 老手,还包含那些曾经把握 Redis 应用办法的人。不晓得后半句是出于何种目标写的,然而通过浏览本书后,我能够说后半句齐全是误导人。这薄薄的一本书,仅仅是一本 Redis 入门指导书,曾经把握了 Redis 应用办法的人,是齐全没有必要通过本书学习 Redis 的。本书介绍了 Redis 的装置,5 种数据类型及操作这些数据类型的常用命令,常见操作(如:事务,过期工夫,排序,音讯告诉,管道等)的实现,脚本,长久化,集群。能够说蕴含了 Redis 大部分的内容,对于初学者而言,这本书能够作为一张地图,初学者依照这种地图走,就能进入 Redis 的世界。当然,这本书并不深刻,为何说没有深刻呢?举个例子,比方介绍数据类型,并没有从源代码这一档次上进行剖析。 这是一本 合格 的入门书。这里想强调一下“合格”二字。别看这是一本入门书,然而这本书对知识点的解说是清晰的,有逻辑性的——即讲清楚了这是什么,为什么要应用,什么时候呈现的。比方“Lua 脚本”这个知识点,什么是Lua 脚本,为什么应用 Lua 脚本,脚本是什么时候呈现的?作者是这样解释的: Redis 在 2.6 版本推出了脚本性能,容许开发者应用 Lua 语言编写脚本传到 Redis 中执行......应用脚本的益处如下: (1)缩小网络开销...... (2)原子操作...... (3)复用...... 从作者的解释中咱们看出作者对 Redis 的了解是透彻的,同时,作者的解释也让读者更好的了解“Lua 脚本”。咱们学习一个知识点不仅仅是晓得怎么操作,更重要的是晓得这是什么,怎么来的,只有这样咱们能力更好的了解这个知识点,记住这个知识点,正当的使用这个知识点。所以从这个层面上来说,我感觉这是一本合格的书。 对于“过期”的问题。自己购买的是 2015 年 5 月第 2 版(2020 年 3 月 河北第 20 次印刷)。而我当初写这篇读后感的工夫是 2021 年 5 月 16 日。所以有些内容确实“过期”了,比方第 34 页的 HMSET 命令,当初曾经不举荐应用了;比方新增的数据类型 HyperLogLogs 也没有介绍......受限于成书工夫以及 Redis 的倒退,这是难以避免的,但这本书把书上的内容讲述好了,所以在我看来是一本好书。万事开头难,即便当初是 2021 年,间隔该书第一次出版曾经过来了 6 年,对于齐全没有接触过 Redis 的初学者而言,我感觉这本书作为入门指导书是十分适合的。对于曾经把握了 Redis 用法的人而言,那么我感觉就齐全没有必要以这本书作为 Redis 的学习材料了。 ...

May 16, 2021 · 1 min · jiezi

关于redis:redis发布与订阅的实现

订阅音讯redis两种订阅形式 订阅频道(subscribe, unsubscribe) ,精准订阅某个key订阅模式(psubscribe, punsubscribe),基于正则订阅某key服务器记录订阅客户端的数据结构 struct redisServer { // 字典+链表,记录订阅频道客户端 {string: list<redisClient>]} dict *pubpub_channels; // 链表记录订阅模式客户端 list<{client: *redisClient, pattern: *robj}> list *pubpub_patterns;}发送音讯publist <channel> <message> 接管音讯订阅频道接管音讯格局 [message, <channel>, <content>]订阅模式接管音讯格局 [pmessage, <pattern>, <channel>, <content>]

May 16, 2021 · 1 min · jiezi

关于redis:动手实践Redis主从复制Sentinel主从切换Cluster分片

背景简介Redis 提供的如下技术「Redis Sentinel『主从切换』、Redis Cluster『分片』」,无效实现了 Redis 的高可用、高性能、高可伸缩性,本文对以上技术进行亲自动手实际。 1. Redis Sentinel「主从切换」监控主从节点的在线状态,并依据配置自行实现切换「基于raft协定」。主从复制从容量角度来说,还是单机。2. Redis Cluster「分片」通过一致性 hash 的形式,将数据扩散到多个服务器节点:设计了 16384 个哈希槽,并调配到多台 redis-server。当须要在 Redis Cluster 中存取一个 key 时,Redis 客户端先对 key 应用 CRC16 算法计算一个数值,而后对 16384 取模,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,而后在此槽对应的节点上操作。一、主从复制设置详情# 已知网关 IP 为:172.17.0.1# 启动 master 节点docker run -it --name redis-6380 -p 6380:6379 redisdocker exec -it redis-6380 /bin/bashredis-cli -h 172.17.0.1 -p 6380# 启动slave节点 1docker run -it --name redis-6381 -p 6381:6379 redisdocker exec -it redis-6381 /bin/bashredis-cli -h 172.17.0.1 -p 6381replicaof 172.17.0.1 6380# 启动slave节点 2docker run -it --name redis-6382 -p 6382:6379 redisdocker exec -it redis-6382 /bin/bashredis-cli -h 172.17.0.1 -p 6382replicaof 172.17.0.1 6380之后可查看 master 节点的信息,在 master-redis 下,执行: ...

May 15, 2021 · 4 min · jiezi

关于redis:缓存穿透击穿雪崩以及解决方案干货满满

缓存的设计蕴含很多技巧,设计不当将会导致重大的结果。redis作为一种非关系型数据库,也总是免不了有各种各样的问题,本文将介绍缓存应用中常见的三大问题,缓存穿透、缓存击穿和缓存雪崩,并给出相应的解决方案。 缓存穿透,击穿,雪崩以及解决方案,干货满满 1、什么是缓存穿透 key对应的数据在数据源并不存在,每次针对此key的申请从缓存获取不到,申请都会压到数据源,从而可能压垮数据源。比方用一个不存在的用户id获取用户信息,不管缓存还是数据库都没有,若黑客利用此破绽进行攻打可能压垮数据库。 缓存穿透解决方案 一个肯定不存在缓存及查问不到的数据,因为缓存是不命中时被动写的,并且出于容错思考,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次申请都要到存储层去查问,失去了缓存的意义。 解决方案: 对空值缓存:如果一个查问返回的数据为空(不论是数据是否不存在),咱们依然把这个空后果(null)进行缓存,设置空后果的过期工夫会很短,最长不超过五分钟设置可拜访的名单(白名单):应用bitmaps类型定义一个能够拜访的名单,名单id作为bitmaps的偏移量,每次拜访和bitmap外面的id进行比拟,如果拜访id不在bitmaps外面,进行拦挡,不容许拜访。采纳布隆过滤器:(布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)。布隆过滤器能够用于检索一个元素是否在一个汇合中。它的长处是空间效率和查问工夫都远远超过个别的算法,毛病是有肯定的误识别率和删除艰难。)将所有可能存在的数据哈希到一个足够大的bitmaps中,一个肯定不存在的数据会被 这个bitmaps拦挡掉,从而防止了对底层存储系统的查问压力。进行实时监控:当发现Redis的命中率开始急速升高,须要排查拜访对象和拜访的数据,和运维人员配合,能够设置黑名单限度服务。 2、什么是缓存击穿 key对应的数据存在,但在redis中过期,此时若有大量并发申请过去,这些申请发现缓存过期个别都会从后端DB加载数据并回设到缓存,这个时候大并发的申请可能会霎时把后端DB压垮。 缓存击穿解决方案 key可能会在某些工夫点被超高并发地拜访,是一种十分“热点”的数据。这个时候,须要思考一个问题:缓存被“击穿”的问题。 解决问题: 事后设置热门数据:在redis顶峰拜访之前,把一些热门数据提前存入到redis外面,加大这些热门数据key的时长实时调整:现场监控哪些数据热门,实时调整key的过期时长应用锁:就是在缓存生效的时候(判断拿进去的值为空),不是立刻去load db。先应用缓存工具的某些带胜利操作返回值的操作(比方Redis的SETNX)去set一个mutex key,当操作返回胜利时,再进行load db的操作,并回设缓存,最初删除mutex key。当操作返回失败,证实有线程在load db,以后线程睡眠一段时间再重试整个get缓存的办法。 3、什么是缓存雪崩 key对应的数据存在,但在redis中过期,此时若有大量并发申请过去,这些申请发现缓存过期个别都会从后端DB加载数据并回设到缓存,这个时候大并发的申请可能会霎时把后端DB压垮。 缓存雪崩与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key 失常拜访缓存生效霎时 缓存雪崩解决方案 缓存生效时的雪崩效应对底层零碎的冲击十分可怕! 解决方案: 构建多级缓存架构:nginx缓存 + redis缓存 +其余缓存(ehcache等) 应用锁或队列:用加锁或者队列的形式保障来保障不会有大量的线程对数据库一次性进行读写,从而防止生效时大量的并发申请落到底层存储系统上。不实用高并发状况 设置过期标记更新缓存:记录缓存数据是否过期(设置提前量),如果过期会触发告诉另外的线程在后盾去更新理论key的缓存。 将缓存生效工夫扩散开:比方咱们能够在原有的生效工夫根底上减少一个随机值,比方1-5分钟随机,这样每一个缓存的过期工夫的反复率就会升高,就很难引发个体生效的事件。 上一篇:微信小程序直播间开发抽红包性能

May 14, 2021 · 1 min · jiezi

关于redis:缓存和数据库数据的一致性的问题

如何保障缓存和数据库数据的一致性更新机制2种更新机制的阐明 1. 触发更新用户发动申请,缓存生效,从数据库中读取数据,更新缓存 2. 被动更新管理员在后盾批改数据,删除缓存或者更新缓存 个别状况2种更新机制同时应用缓存和数据库数据的一致性策略1. 双写 - 先更新数据库,再更新缓存被动+触发管理员后盾批改数据,同时用户发动申请,脏数据的可能性 工夫T1T2T3T4T5被动更新 更新数据库更新缓存触发更新读缓存,生效读数据库 更新缓存双被动2个管理员后盾同时批改数据,小概率 工夫T1T2T3T4被动更新A更新数据库 更新缓存被动更新B 更新数据库更新缓存 双触发双触发更新,最多导致2次更新缓存,个别加锁只更新1次 总结双写会有2个问题 脏数据的小概率事件性能节约有认为你应用了缓存,必然是热数据,申请会很多,你不被动更新缓存,也会有用户触发更新缓存,并不存在性能上的节约。但不意味着每时每刻、所有数据都会被频繁申请,因而双写必然会导致局部性能的节约 2. 先删除缓存,再更新数据库会导致被动+触发,写入脏数据概率减少 3. 先更新数据库,再删除缓存被动+触发,仍然有概率写入脏数据 4. 先更新数据库,再提早删除缓存提早计划代码间接提早,取决更新工夫删除操作退出队列,提早解决删除操作先删除操作,退出队列,再提早队列问题队列数据失落的问题解决队列操作时间差,缓存数据不统一

May 14, 2021 · 1 min · jiezi

关于redis:路上小胖问我Redis-主从复制原理是怎样的

00 前言我负责我司的报表零碎,小胖是我小弟。随着业务量的减少,单实例顶不住,我就搭建了多个 Redis 实例,实现主从模式。 好学的小胖就问我啊,远哥,多实例之间的数据是怎么放弃同步的呀?你教教我好不好嘛~ 我拿起手中 82 年的开水抿了一口,跟小胖说:你先看这篇文章,学会了操作,我再给你讲讲原理吧。 https://juejin.cn/post/684490... 老规矩,还是先上脑图:(PS:文末有我筹备的大厂面试题) 0.1 往期精彩MySQL 查问语句是怎么执行的? MySQL 索引 MySQL 日志 MySQL 事务与 MVCC MySQL 的锁机制 Redis 根底 Redis 长久化 01 主从复制Redis 的高牢靠次要由两点保障,一是数据尽量少失落,二是服务尽量少中断。长久化保障了第一点;而第二点则由 Redis 集群保障,Redis 的做法就是多实例保持数据同步。 1.1 读写拆散Redis 提供了主从库模式,以保证数据正本的统一,主从库之间采纳的是读写拆散的形式。 读操作:主库、从库都能够接管;写操作:首先到主库执行,而后,主库将写操作同步给从库。 为什么要读写拆散呢?看看上图,如果所有库都能够写,那将会产生一个 key 在不同实例就有不同的值。比方上图对应的键 k1 在不同实例就有不同的 v1、v2、v3 值,这是相对不能承受的。 有人说,,能够加锁呀然而这会波及到加锁、实例间协商是否实现批改等一堆操作,带来巨额的开销,Redis 以快著称,这也是不能承受的。 那咋办呀?读写拆散咯主从库模式采纳读写拆散,所有数据批改只会在主库进行。主库有最新数据,会同步给从库,这样,主从库的数据就是统一的。 问题就在同步了,主从库之间是怎么同步的呢?一起来探讨下 1.2 全量复制当咱们启动多个 Redis 实例的时候,它们相互之间就通过 replicaof(Redis 5.0 之前应用 slaveof)命令造成主库和从库的关系,之后会依照三个阶段实现数据的第一次同步。 比方当初有实例1(127.0.0.1)和实例2(127.0.0.2),在实例 2 执行 replicaof 后,实例 2 就变成实例 1 的从库啦。 replicaof 127.0.0.2 6379建设关系之后,Redis 会进行第一次全量复制。过程如下: ...

May 13, 2021 · 1 min · jiezi

关于redis:Redis迁移工具redisshake

https://github.com/alibaba/Re... 一、从rdb文件迁徙数据到阿里云上主从版Redis1、输入配置文件(redis-shake-habor.conf) 2、启动迁徙工作 ./redis-shake.linux -type=restore -conf=redis-shake.conf3、察看日志,并验证源端及指标端key数量

May 13, 2021 · 1 min · jiezi

关于redis:记录本地环境问题导致项目启动失败

1.问题明天本地环境启动springboot我的项目,始终卡住,始终没有看到启动胜利日志。我本地环境应用的中间件是本地搭建的。 2.最终解决办法因为我本地redis是通过命令行窗口关上的,一段时间没有应用,处于假死状态,把窗口激活一下,重新启动就能够了

May 12, 2021 · 1 min · jiezi

关于redis:Instagram-为什么不用redis

Hi 我还是大粽子 碎碎念让我比拟兴奋的就是这段时间的文章,被感兴趣的同学一一关注,关注量上涨就是我的最大能源。 我每周都会输入至多3篇原创文章,心愿能被更多的同学关注,点赞,在看,造成习惯。 Instagram 为什么不必redisInstgram FB 旗下的专一图片社交的APP (不找美照哦!也就是大家说的ins风) 如果我没猜错,这可能与以下事实无关: Redis中的所有数据都须要保留在内存中,而Cassandra则将数据写入磁盘。大规模(以及应用大型数据集)将所有数据保留在内存中可能会变得十分低廉。 老本老本还是老本无论Redis专家还是Cassandra的老手,但据我所见,Cassandra的劣势如下。 分布式-易于复制(主动复制)。更少的停机工夫-即便所有节点都停机,也能够配置为做出响应。高可用性-如果您以奇妙的形式对数据进行建模并将其搁置在正确的分区和节点中,那么即便您不小心删除了数据(压缩设置),也不会失落任何数据。劫难复原-这很容易,就像与Cassandra一块蛋糕一样,加上no-3,它是数据管理的绝佳抉择。API-大多数规范语言都具备用于通信的API(JAVA,PYTHON,RUBY,SCALA)。易于测试能够作为服务进行保护。宽泛的文档和帮忙SStables是文件,因而即便长时间失败而不是您配置的设置,您也能够备份它们并还原节点,而不会失落任何数据。大量的数据处理和扩大-轻松轻松地解决大数据和海量数据。扩大实际上是将节点增加到任何群集中,并且只需进行简略的配置即可。 如果有错,请私信我纠正。看看DB-ENGIN 依据受欢迎水平的一个排名 日常求关注,素质一键三连。每周至多3篇原创文章,在被业务折磨的状况下还能留下点什么。最近很喜爱的一句话 “有道无术,术尚可求。有术无道,止于术。”

May 11, 2021 · 1 min · jiezi

关于redis:强上线3天获10w浏览量京东T8纯手码Redis缓存手册我粉了

Hello,明天给各位童鞋们分享Redis缓存,连忙拿出小本子记下来吧! 简介什么是Redis?Redis是一种存储系统,像MongoDB一样,都是键值对存储,也就是key-value构造。也就是说,Redis其实是一种数据库,它能够跨平台应用,本系列整合SpringBoot+Redis。 Redis自身是由C语言编写,是合乎ANSI C规范的开源零碎。Redis是Remote Dictionary Server的缩写,当初罕用于分布式数据库以及高可用缓存零碎。实际上,学会Redis整合了SpringBoot后,再整合SpringCloud就是瓜熟蒂落了。 为什么要用Redis?有敌人可能要问,既然Redis和MongoDB这么像,那我用后者不就行么,干嘛学前者?实际上MongoDB和Redis是有很大区别的,他们只是在存储形式上有类似点。上面列出二者的不同之处: 数据存储地位MongoDB存储的数据寄存在磁盘,少部分数据寄存在内存中。为啥数据库数据还要寄存在内存呢?是因为数据库的缓存零碎会判断热点数据,频繁存取的数据要放在内存达到高效解决。 Redis的数据全副寄存在内存,并定期写入磁盘,也因而造就了Redis的高性能。当内存不够用,Redis会利用LRU(Least Recently Used)算法取代数据,没错,就是操作系统西面置换算法。 数据存储形式MongoDB利用了mmap函数,将文件数据映射的内存进行增删查改,批改完之后操作系统会将内存数据flush到磁盘。问题是二者并非一个事务,因而两个事务间宕机的话,数据天然失落。 Redis有两种存储模式,RDB与AOF模式,这个咱们前面会说到。 数据处理速度MongoDB比Redis慢,这也是Redis属于内存存储系统的最大劣势。当然,咱们临时不思考内存不够用的状况。 除此之外,目前分布式是大厂支流技术栈,Redis是大厂会采纳的分布式缓存形式。并且在应答高并发的场景上,比方阿里双十一,腾讯游戏新皮肤的出场或者过年红包等,利用Redis和音讯队列是支流的办法。 入门是什么水平?精通是什么水平?入门就是对Redis齐全不理解,然而你要有根底的常识,比方根底的数据结构,根底的类型,根底的内存常识,根底的分布式常识, 根底的Java/Spring常识和linux的基本操作。这个大可释怀,我程度也一般般,所以我说的根底肯定是根底。 精通并不是说最初能本人写一个Redis,或者说本人能成为Redis的稳固开发维护者,我本人也做不到,所以这里的精通是可能理解Redis的各种机制、算法,理解Redis提供的罕用办法,理解Redis应用场景,本人能排坑,并且可能本人整合SpringBoot框架。实际上,这个整合SpringBoot框架最简略,官网写的很具体。最好能在Redis根底上进行二次开发,实际上了解了原理,会写C语言,二次开发还是不难的。 既然是系列文章,我就不能全写在一篇里,内容太多对于我的排版和学习者的体验也不好,所以我会尽量把每一篇文章压缩在一个能够承受的长度范畴,当然,我尽量在每一篇文章都给出系列所有文章的链接,供大家,也供我日后不便查阅。如果文章能帮到你,心愿给个赞激励下,尽管不是靠这个生存,然而失去认可还是很快乐的。 缓存以及应用场景什么是缓存?缓存实际上就是某个程序利用内存来优化频繁读取的数据的一种形式。缓存就是内存的一部分。之前咱们写到,数据库操作往往是存储在磁盘中的,然而磁盘的IO又慢的不得了,怎么办?程序猿们想了一种办法,就是利用好内存。不是磁盘IO慢么,那就利用内存好了,内存IO很快的,然而货色太多,放不进内存怎么办?那就把罕用的数据放在内存吧。 当初是2021年,相熟NBA的敌人都晓得,往年威少的数据又爆炸,所以球迷可能会时常看威少的数据,加上威少的粉丝也不少,可能就存在高并发的问题。然而每次从磁盘拿数据也太慢了,那就把独自把威少的数据放在内存中,他人的数据持续躺在磁盘里,这样大大放慢了零碎响应的速度,这就是缓存。 然而,NBA可不止有一个球星,库里,詹姆斯,约基奇等都是很杰出的球员,领有球迷的数量不比威少少,那就把他们的数据都放在缓存中吧,这样就快了。然而咱们发现,NBA球星太多了,内存放不下,怎么办?这就引出了咱们的常见的缓存淘汰算法,对操作系统有理解的敌人可能晓得,什么LRU,LFU,FIFO,FILO等等,我把这个放在前面的Redis算法机制里说。 本地缓存与分布式缓存先看看例子,还是NBA球员,当初我的内存太小了啊,每个计算机只能寄存一名NBA球员的数据,然而我当初有3名球员数据须要寄存在计算机外面怎么办? 本地缓存本地缓存就是将数据寄存在本地内存中,因为不须要通过网络连接到其余主机,天然速度也最快,当然毛病也是有的。比方Mybatis一二级缓存,Caffeine,Guava都是本地缓存的典型范例。回到之前的例子,3名球员放在3台不同的主机,如果用本地缓存的架构就是这样的: 长处: 速度快,不必通过网络传输 毛病: 每台主机可用缓存容量无限 多节点无奈共享数据 分布式缓存分布式缓存就是利用网络,将缓存放在某一台主机上,这样缓存的容量限度就是缓存机的内存大小,其IO瓶颈就是网速。Redis就是典型的分布式缓存,当然,咱们也能够让Redis变成彻头彻尾的本地缓存,不经网络调用即可。 当然,上图并不精确,既然缓存的分布式了,当然不能只部署在一台缓存机上,往往都是集群的形式部署缓存机的。 热点Key问题什么是热点key呢?很简略,咱们看到微博时常会宕机,除了用户量大,信息量多以外,往往是某个明星又发表“咱们有个孩子”这类的事件,有数用户拜访该资源,该资源对应的key就被称为热点key,忽然间的高并发,使得某一个热点被高频拜访,从而导致服务器缓存资源耗竭,怎么解决? 解决办法有很多,然而咱们明天说到缓存问题了,就只说缓存解决方案。拿明星有了孩子举例子,从起因剖析到解决方案,其实起因有了,解决方案就是信手拈来的事件了。 起因剖析:某明星A与某明星B有了孩子,A和B在分布式缓存服务器上,然而当这种爆炸性新闻产生的时候,大量用户拜访分布式缓存服务器,即便缓存资源没有耗尽,网络IO也无奈承载。因为咱们的假如是key在一台机器,那么临时不思考拆分key的状况,就是缓存临时能顶得住,然而网络IO崩了,分布式缓存服务器接受不了那么大的数据量,怎么办? 解决办法:既然解决不了网络的问题,那就不解决了,罗唆不必,毕竟扩充网络带宽这种在行都懂的办法入不了咱们的法眼。怎么不必?那就是本地缓存+分布式缓存。网络受不了,就把高频资源放在本地服务器上,外界拜访相干资源,间接从本地服务器取,和分布式缓存服务器无关。只有当新来的高频资源拜访,且老高频资源热度上来时,取代即可。 好啦,明天的文章就到这里,心愿能帮忙到屏幕前迷茫的你们

May 10, 2021 · 1 min · jiezi

关于redis:大佬用-Redis-实现一个轻量级的搜索引擎牛x啊

场景大家如果是做后端开发的,想必都实现过列表查问的接口,当然有的查问条件很简略,一条 SQL 就搞定了,但有的查问条件极其简单,再加上库表中设计的各种不合理,导致查问接口特地难写,而后加班什么的就不用说了(不知各位有没有这种感触呢~)。 上面以一个例子开始,这是某购物网站的搜寻条件,如果让你实现这样的一个搜寻接口,你会如何实现?(当然你说借助搜索引擎,像 Elasticsearch 之类的,你齐全能够实现。但我这里想说的是,如果要你本人实现呢?) 从上图中能够看出,搜寻总共分为6大类,每大类中又分了各个子类。这两头,各大类条件之间是取的交加,各子类中有单选、多选、以及自定义的状况,最终输入符合条件的后果集。 好了,既然需要很明确了,咱们就开始来实现。 实现1率先退场是小A同学,他是写 SQL 方面的“专家”。小A信念满满的说:“不就是一个查问接口吗?看着条件很多,但凭着我丰盛的 SQL 教训,这点还是难不倒我的。” 于是乎就写出了上面这段代码(这里以 MYSQL 为例): select ... from table_1left join table_2left join table_3left join (select ... from table_x where ...) tmp_1...where ...order by ...limit m,n代码在测试环境跑了一把,后果如同都匹配上了,于是筹备上预发。这一上预发,问题就开始裸露进去。预发为了尽可能的真切线上环境,所以数据量自然而然要比测试大的多。所以这么一个简单的 SQL,它的执行效率可想而知。测试同学果决把小A的代码给打了回来。 实现2总结了小A失败的教训,小B开始对SQL进行了优化,先是通过了explain关键字进行SQL性能剖析,对该加索引的中央都加上了索引。同时将一条简单SQL拆分成了多条SQL,计算结果在程序内存中进行计算。 伪代码如下: $result_1 = query('select ... from table_1 where ...');$result_2 = query('select ... from table_2 where ...');$result_3 = query('select ... from table_3 where ...');...$result = array_intersect($result_1, $result_2, $result_3, ...);这种计划从性能上显著比第一种要好很多,可是在性能验收的时候,产品经理还是感觉查问速度不够快。小B本人也晓得,每次查问都会向数据库查问屡次,而且有些历史起因,局部条件是做不到单表查问的,所以查问期待的工夫是防止不了的。 实现3小C从下面的计划中看到了优化的空间。他发现小B在思路上是没问题的,将简单条件拆分,计算各个子维度的后果集,最初将所有的子后果集进行一个汇总合并,失去最终想要的后果。 于是他突发奇想,是否当时将各个子维度的后果集给缓存起来,这要查问的时候间接去取想要的子集,而不必每次去查库计算。 ...

May 10, 2021 · 1 min · jiezi

关于redis:Redis-RDB持久化

1、RDB长久化,什么叫 长久化?1、1: 将数据库中的数据/状态保留到磁盘的过程。 1、2: 长处:避免数据失落,fork子过程解决不影响主过程(bgsave),适宜大规模的数据恢复 1、3: 毛病:最初一次长久化后的数据可能失落,Fork的时候,内存中的数据被克隆了一份,大抵2倍的膨胀性须要思考2、长久化过程2、1: 形式:save(rdbSave())、bgsave(fork() + rdbSave())2、2: rdb文件的载入是主动的(rdbLoad),没有手动命令2、3: 能够设置多个bgSave条件,满足其一即主动执行bgSave。碰撞时则进入排队?回绝?2、4: SAVE会阻塞redis服务器2、5: (存)数据库状态->rdb文件。(取)服务器启动-> 执行载入程序-> 优先载入aof文件 -> 没有aof文件载入rdb文件3、dirty计数:记录写入、删除、更新等操作的次数。3、1:lastsave记录上次执行SAVE/BGSAVE的UNIX工夫。3、2:dirty计数在SAVE/BGSAVE之后重置4、serverCron:4、1: 100ms执行一次。4、2: 查看savepramas,满足一条即执行BGSAVE(应用dirty计数器判断)4、3: 保留为2进制文件5、database:5、1: rdb文件 = redis字符 (标记是rdb文件) + db_version(版本号) + 非空数据库 + eof(是否载入标识) + check_sum (查看统计)5、2: 非空数据库 = select_db(常量,接下来要读入的数据库号码) + db_number (数据库号码) + key_value_pairs(键值对)5、3: 键值对 = type(值类型) + key (键对象) + value (值对象)5、4: 带有过期工夫的键值对 = type(值类型) + key (键对象) + value (值对象) + expiretime_ms (标识位) + ms (8字节长的UNIX工夫 戳)6、value类型: STRING、REDIS_RDB_TYPE_LIST、REDIS_RDB_TYPE_SET、REDIS_RDB_TYPE_HASH、REDIS_RDB_TYPE_ZSET、REDIS_RDB_TYPE_INSERT(整数汇合对象)、REDIS_RDB_TYPE_ZIPLIST(压缩列表对象)7、RDB文件剖析:7、1: 能够应用od命名剖析rdb文件,如:od -c dump.rdb7、2: 不蕴含任何键值对的rdb文件。(与5.1中的比照,非空数据库?)

May 8, 2021 · 1 min · jiezi

关于redis:Redis-数据库

1、redis.h / redisDB 构造?2、通过redisClient实现 DB切换,通过每次都select db防止误操作3、键空间操作实现redisDB操作。(SET、DEL、GET等罕用)(FLUSHDB、RANDOMKEY、KEYS、DBSIZE、EXISTS等不罕用)4、键空间保护:(1)hits命中次数、miss未命中次数。 (2)LRU最初一次应用工夫 4.1问题:redis在读取一个key并发现其已过期,会先删除这个key。删除过期key的形式之一?还有?答:定时删除、定期删除、惰性删除即上述拜访才会删除的策略 4.2问题:key被更新后会按设置发送告诉。可用性?业务场景?5、过期工夫EXPIRE/PEXPIRE(秒/毫秒)、EXPIREAT/PEXPIREAT(工夫戳/毫秒工夫错)。保留在过期字典中(相似键空间保留了所有键值对)5.1问题:永恒无效的键值对有过期字典吗?没有6、PERSIST:移除过期工夫,TTL、PTTL:计算残余生存工夫7、RDB长久化是指在指定的工夫距离内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子过程,先将数据集写入临时文件,写入胜利后,再替换之前的文件,用二进制压缩存储。 比照 : AOF长久化以日志的模式记录服务器所解决的每一个写、删除操作,查问操作不会记录,以文本的形式记录,能够关上文件看到具体的操作记录。抉择 : RDB罕用8、数据库告诉:键空间告诉(某个key执行了什么命令)键事件告诉(某个命令被什么key执行了)。问题:什么是告诉函数?后续章节有介绍,再补充

May 8, 2021 · 1 min · jiezi

关于redis:Redis-AOF持久化

Redis AOF 长久化1、AOF长久化蕴含的命令:1.1 SET 1.2 SADD(将一个或多个成员元素退出到汇合中,曾经存在于汇合的成员元素将被疏忽。Redis2.4 版本以前,SADD只承受单个成员值。)(set add) 1.3 RPUSH (将一个或多个值插入到列表的尾部)2、AOF长久化的实现:命令追加、文件写入、文件同步2.1 追加到aof_buf缓冲区的开端,协定格局: 2.1.1 文件头(和RDB文件头格局雷同) 2.1.2 RDB格局的二进制数据段 2.1.3 AOF格局的文本数据段 2.2 文件写入:flushAppendOnlyFile() 将aof_buf缓冲区的内容写入到aof文件。 问:flushAppendOnlyFile的选项值 appendfsync蕴含了: 1)always,写入并同步。 2)everysec:写入,超过1秒再同步到aof文件,默认值。 3)写入,不同步。 这里的写入和同步是什么意思? 答:是操作系统的写入和同步,在调用write函数时,是先将内容写入数据缓冲区的,当缓冲区满或超过特定时限才会写入磁盘2.3 AOF文件载入与数据还原 步骤:启动载入 -> 创立伪客户端(无网络链接)-> (1)从AOF取命令 -> (2)读取、发送并执行一条命令 -> 载入实现 注:上述步骤(1)和(2)是loop执行的3、AOF 的重写3.1 目标:解决AOF 文件体积收缩3.2 实现原理:创立新的AOF文件代替原有的AOF文件,替换过程剔除了冗余命 如将 RPUSH A + RPUSH B 两条命令 精简为 RPUSH A, B3.3 aof_rewrite 函数 是下载所有redis db 数据的过程3.4 同RDB长久化雷同,AOF 重写过程也是fork子过程解决的3.5 fork子过程解决重写时,主过程失常解决客户端命名(非阻塞)。 为保证数据一致性,当执行一个命令之后,会同时给AOF缓冲区(2.2所述)和AOF从新缓冲区(AOF重写启动时创立)发送命令。 重写完结时再将AOF缓冲区的命令写入新的AOF文件4、问题:4.1 RDB长久化 和 AOF长久化咱们应用的是哪个?咱们对redis的应用场景大部分都是缓存,对数据的安全性要求并不是很高,选 RDB 4.2 如果咱们应用 AOF长久化,appendfsyc参数值该如何选?我感觉是everysec,在性能和数据安全上的取舍是中庸的4.3 AOF的重写 和 RDB长久化很类似,都是下载redis db数据到磁盘。保留的文件格式是不同的

May 8, 2021 · 1 min · jiezi

关于redis:最佳实践丨在云函数内使用-Redis-扩展

什么时候应该应用 Redis?Redis 的实用场景包含但不仅限于: 计数器:因为 Redis 操作是原子性的,通过原子递增或递加来做高并发用户的数据计数,比方点赞数、珍藏数、分享数、商品抢购时的库存量、商品文章总数、评论数量等;排行榜:Redis 反对汇合和有序汇合的数据结构,且运行在内存中,因而能够存储一些相似于排行榜的数据,比方最近、最热、点击率最高、活跃度最高、评论最多等等的文章、商品、用户等;哈希表:用户粉丝列表、用户点赞列表、用户珍藏列表、用户关注列表等;主动排序:存储工夫戳,随着工夫的变动,依照用户关注用户的最新动静列表等主动排序;会话缓存:应用 Redis 进行会话缓存,将 web session 寄存在 Redis 中;全页缓存 FPC:能够将服务端渲染后果的缓存在 Redis 中;记录用户操作信息:用户是否点赞、用户是否珍藏、用户是否分享等。装置 Redis 拓展1、装置扩大关上腾讯云控制台,进入到环境详情页面,点击左侧的「扩大利用」,进入到扩大能力详情页,并点击 Redis 拓展,装置拓展。 2、创立 Redis 实例假使装置中没有实例(即还没有购买 Redis 数据库,点击新建实例),假使曾经有实例的能够跳过,进入下一步。 购买 Redis 数据库,创立实例,装备好公有网络。 创立好实例后回到扩大抉择刚刚创立(或者已有的)的实例: 点击实现创立: 看到有如下扩大即装置胜利: 3、获取 Redis 信息创立好后查看拓展相干信息(在这外面咱们便能够看到一起创立好的云函数啦): 在云函数中应用 Redis云函数内能够通过 Redis 客户端连贯和操作 Redis 实例,举荐应用。 1、装置依赖首先进入到 Redis 的云函数目录中,而后执行命令 npm init -y 初始化一个配置文件。 随后,执行 npm install --save redis 来装置相应的依赖。 装置实现后,云函数目录下将会呈现 package.json 文件,内容相似以下: {"name": "redis","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"redis": "^3.0.2"}}2、调用 Redis接下来能够在代码中调用 Redis 数据库了。 ...

May 7, 2021 · 1 min · jiezi

关于redis:Redis-官方的高可用解决方案请收藏

Redis主从复制的问题Redis 主从复制可将主节点数据同步给从节点,从节点此时有两个作用: 一旦主节点宕机,从节点作为主节点的备份能够随时顶上来。扩大主节点的读能力,分担主节点读压力。 主从复制同时存在以下几个问题: 一旦主节点宕机,从节点降职成主节点,同时须要批改利用方的主节点地址,还须要命令所有 从节点去复制新的主节点,整个过程须要人工干预。主节点的写能力受到单机的限度。主节点的存储能力受到单机的限度。原生复制的弊病在晚期的版本中也会比较突出,比方:Redis 复制中断后,从节点会发动 psync。此时如果同步不胜利,则会进行全量同步,主库执行全量备份的同时,可能会造成毫秒或秒级的卡顿。在民工哥技术之路公众号后盾回复关键字  Redis手册  收费获取一份redis最佳实际与实战指南电子书Redis 的 哨兵(Sentinel)深刻探索Redis Sentinel的架构 Redis的哨兵机制就是解决咱们以上主从复制存在缺点(选举问题),保障咱们的Redis高可用,实现自动化故障发现与故障转移。 该零碎执行以下三个工作: 监控:哨兵会一直查看你的主服务器和从服务器是否运作失常。揭示:当被监控的某个Redis服务器呈现问题时,哨兵能够通过API给程序员发送告诉主动故障转移:主服务器宕机,哨兵会开始一次主动故障转移操作,降级一个从服务器为主服务器,并让其余从服务器改为复制新的主服务器.配置 SentinelRedis 源码中蕴含了一个名为 sentinel.conf 的文件, 这个文件是一个带有具体正文的 Sentinel 配置文件示例。 运行一个 Sentinel 所需的起码配置如下所示: 1)sentinel monitor mymaster 192.168.10.202 6379 2Sentine监听的maste地址,第一个参数是给master起的名字,第二个参数为master IP,第三个为master端口,第四个为当该master挂了的时候,若想将该master判为生效,在Sentine集群中必须至多2个Sentine批准才行,只有该数量不达标,则就不会产生故障迁徙。2)sentinel down-after-milliseconds mymaster 30000示意master被以后sentinel实例认定为生效的间隔时间,在这段时间内始终没有给Sentine返回无效信息,则认定该master主观下线。只有在足够数量的 Sentinel 都将一个服务器标记为主观下线之后, 服务器才会被标记为主观下线,将服务器标记为主观下线所需的 Sentinel 数量由对主服务器的配置决定。3)sentinel parallel-syncs mymaster 2当在执行故障转移时,设置几个slave同时进行切换master,该值越大,则可能就有越多的slave在切换master时不可用,能够将该值设置为1,即一个一个来,这样在某个slave进行切换master同步数据时,其余的slave还能失常工作,以此保障每次只有一个从服务器处于不能解决命令申请的状态。4)sentinel can-failover mymaster yes在sentinel检测到O_DOWN后,是否对这台redis启动failover机制5)sentinel auth-pass mymaster 20180408设置sentinel连贯的master和slave的明码,这个须要和redis.conf文件中设置的明码一样6)sentinel failover-timeout mymaster 180000failover过期工夫,当failover开始后,在此工夫内依然没有触发任何failover操作,以后sentinel将会认为此次failoer失败。 执行故障迁徙超时工夫,即在指定工夫内没有大多数的sentinel 反馈master下线,该故障迁徙打算则生效7)sentinel config-epoch mymaster 0选项指定了在执行故障转移时, 最多能够有多少个从服务器同时对新的主服务器进行同步。这个数字越小, 实现故障转移所需的工夫就越长。8)sentinel notification-script mymaster /var/redis/notify.sh当failover时,能够指定一个"告诉"脚本用来告知以后集群的状况。脚本被容许执行的最大工夫为60秒,如果超时,脚本将会被终止(KILL)9)sentinel leader-epoch mymaster 0同时一时间最多0个slave可同时更新配置,倡议数字不要太大,免得影响失常对外提供服务。主观下线和主观下线主观下线:指的是单个 Sentinel 实例对服务器做出的下线判断。主观下线:指的是多个 Sentinel 实例在对同一个服务器做出SDOWN主观下线判断。Redis Sentinel的工作原理1.每个 Sentinel 以每秒一次的频率向它所知的主服务器、从服务器以及其余 Sentinel 实例发送一个 PING 命令。 ...

May 7, 2021 · 1 min · jiezi

关于redis:envoy代理rediscluster

Redis-Cluser架构设计 Redis-Cluser采纳无核心构造,每个节点都保留数据和整个集群状态,各个节点之间相互链接节点间采纳ping-pong机制互联,外部应用二进制协定传输优化速度和带宽Redis-Cluser会把所有物理节点映射到0-16383个slot上Redis集群预分好16384个桶,当须要在 Redis 集群中搁置一个 key-value 时,依据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中部署Redis-Cluser 3节点(一个正本) redis配置daemonize yesport 7006cluster-enabled yescluster-config-file "nodes.conf"cluster-node-timeout 15000appendonly yesprotected-mode nobind 0.0.0.0masterauth "westos"requirepass westos启动redis执行集群创立redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1envoy配置static_resources: listeners: - name: redis_listener address: socket_address: address: 0.0.0.0 port_value: 1999 filter_chains: - filters: - name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.redis_proxy.v3.RedisProxy stat_prefix: egress_redis settings: op_timeout: 5s prefix_routes: catch_all_route: cluster: redis_cluster clusters: - name: redis_cluster connect_timeout: 1s type: strict_dns # static lb_policy: MAGLEV typed_extension_protocol_options: envoy.redis_proxy: "@type": type.googleapis.com/google.protobuf.Struct value: auth_password: inline_string: "westos" load_assignment: cluster_name: redis_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7001 - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7002 - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7003 - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7004 - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7005 - endpoint: address: socket_address: address: 10.0.2.15 port_value: 7006admin: access_log_path: "/dev/null" address: socket_address: address: 0.0.0.0 port_value: 8001启动envoyenvoy -c envoy.yaml -l debug --service-cluster proxy

May 7, 2021 · 1 min · jiezi

关于redis:Redis

一、实现缓存机制因素1.数据结构应该采纳什么类型? 采纳K-V构造2.内存特点断电即擦除如何避免? 将内存数据进行长久化操作(存到磁盘中)3.内存容量无限,如何只保留热点数据? LRU算法/LFU算法/TTL算法/随机算法4.为了与硬件交互性强,所以采纳C语言的形式进行开发

May 6, 2021 · 1 min · jiezi

关于redis:redis对象

redis中每个对象,都用redisObject示意: struct { // 5大数据类型 unsigned type:4;![](/img/bVcRMBj) // 9大编码类型 unsigned encoding:4; // 最初拜访工夫 unsigned lru:24; // 援用计数 int refcount; // 底层数据结构指针 void *ptr;}数据类型(type)type命令能够输入某个键的对象类型 编码类型object encoding 命令能够输入某个键的编码类型#define OBJ_ENCODING_RAW 0 /* Raw representation */#define OBJ_ENCODING_INT 1 /* Encoded as integer */#define OBJ_ENCODING_HT 2 /* Encoded as hash table */#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */数据类型对应编码类型利用 ...

May 5, 2021 · 1 min · jiezi

关于redis:Redis的使用

全面把握Redis,看这篇文章就够了!后面几遍文章,散布讲述了JS,Docker,Nginx,但写的文章都相当于流水账似的,只是记录了这类语言的语法以及知识点,看似具体,内容很多,实际上并没有什么重点总结,只能作为理解来查漏补缺,不适宜深刻学习。所以,接下来的文章,我会依照本人的思路来总结Redis的知识点!一、Redis是什么?Redis有什么利用场景?Redis是一个开源的应用ANSI C语言编写、恪守BSD协定、反对网络、可基于内存亦可长久化的日志型、Key-Value内存数据库,并提供多种语言的API。Redis在Java Web中次要有两个利用场景: 存储热点数据,作为缓存存于内存中实现高速读/写二、Redis的特点Redis反对数据的长久化,能够将内存中的数据保留在磁盘中,重启的时候能够再次加载进行应用。Redis不仅仅反对简略的key-value类型的数据,同时还提供string,list,set,zset,hash等数据结构的存储。Redis反对数据的备份,即master-slave模式的数据备份。 三、Redis反对的数据结构String字符串:用来缓存一些动态文件,如图片、视频、css文件等。反对incr操作,能够用作计数器,比方统计网站拜访次数等。List列表:微博中“关注、粉丝”、论坛中所有回帖的ID用的就是list列表,还有音讯队列,也是列表。Set汇合:能够疾速查找元素是否存在,用于记录一些不能反复的数据。Zset有序汇合:应用Sorted Set构建一个具备优先级的队列。Hash:实用于存储对象,比方把用户的信息存到hash里,以用户id为key,用户的详细信息为value。 四、redis单线程执行却快的起因?齐全基于内存,绝大部分申请是纯正的内存操作,十分疾速。数据结构简略,对数据操作也简略,Redis中的数据结构是专门进行设计的;采纳单线程,防止了不必要的上下文切换和竞争条件,也不存在多过程或者多线程导致的切换而耗费 CPU,不必去思考各种锁的问题,不存在加锁开释锁操作,没有因为可能呈现死锁而导致的性能耗费;应用多路I/O复用模型,非阻塞IO(NIO); 多路I/O复用模型是利用 select、poll、epoll 能够同时监察多个流的 I/O 事件的能力,在闲暇的时候,会把以后线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正收回了事件的流),并且只顺次程序的解决就绪的流,这种做法就防止了大量的无用操作。这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程,采纳多路 I/O 复用技术能够让单个线程高效的解决多个连贯申请(尽量减少网络 IO 的工夫耗费),且 Redis 在内存中操作数据的速度十分快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,次要由以上几点造就了 Redis 具备很高的吞吐量五、Redis事务相干命令:watch/unwatch:给Keys标记增加/革除为监测态Multi:显示的开启事务,后续commands将排队Exec:执行事务中的commands队列Discard:革除事务中的commands队列事务中的两种谬误:在调用exec命令之前的语法错误,Redis2.6.5之后所有命令不执行在调用exec命令之后的谬误(误操作),其余命令照样执行并返回后果Redis事务中不反对回滚RollbackRedis命令产生谬误,其余命令照样执行,而不会回滚,这些谬误都是开发中可能被检测进去的,在理论中不应该呈现的谬误,所以不用反对回滚,使Redis外部简洁并且更加高效。六、Redis两种长久化形式快照长久化:Redis能够通过创立快照来取得存储在内存外面的数据在某个工夫节点上的正本。在创立快照之后,用户能够对快照进行备份,能够将快照复制到其余服务器从而创立具备雷同数据的服务器正本,还能够将快照留在原地以便重启服务器时应用。创立快照:1)客户端BGSAVE命令2)SAVE指令,不罕用,当内存不足以执行BGSAVE时应用3)save配置选项,比方save 60 10000 60秒内有10000次写入触发BGSAVE4)客户端shutdown时,执行SAVE5)连贯从服务器时,主服务器会执行BGSAVE创立快照问题:如果零碎产生解体,用户将失落最近一次生成快照之后更改的所有数据。AOF长久化简略来说,AOF长久化会将被执行的写命令写到AOF文件的开端,以此来记录数据产生的变动。因而,Redis只有从头到尾从新执行一次AOF文件蕴含的所有写命令,就能够复原AOF文件所记录的数据集。同步策略:1)always:每个写命令都要同步写入磁盘,重大升高Redis速度2)everysec:每秒执行一次同步3)no:让操作系统来决定何时进行同步问题:1.失落大量数据,依据不同同步策略。2.AOF文件会越来越大(AOF文件重写)七、Redis主从复制一主二从时,客户端每次向主服务器写入数据时,通过复制主服务器的数据正本,从服务器实时更新数据。这样主服务器负责写数据,从服务器负责读数据,实现读写拆散。八、Redis集群

May 4, 2021 · 1 min · jiezi

关于redis:RDB持久化

什么是RDBredis将内存中的数据存储到磁盘上的二进制文件。通过该文件,能够在启动时,还原数据库状态(数据)。 载入和写入载入仅在服务启动时载入。AOF优先载入,如果没有开启AOF的时候,载入RDB SAVE命令服务过程写入。回绝其它客户端命令 BGSAVE命令子过程写入。回绝SAVE、BGSAVE命令 主动保留配置文件中的save项,示意x秒内保留>n次,触发BGSAVE主动保留。多个save配置,满足一个即触发。 save SECONDS SAVE_TIMES 保留条件读入redisServer对象中,相干字段 struct redisServer { struct saveparams *saveparams; // 保留条件数组 long dirty; // 批改计数器 time_t lastsave; // 上次保留工夫}struct saveparams { time_t seconds; int changes;}RDB文件构造

April 30, 2021 · 1 min · jiezi

关于redis:Redis-集群主从复制原理

一、前言通过 Redis 的长久化性能,保障了 Redis 在宕机重启的状况下也不会失落(或者失落极少局部)数据。然而这只局限在单机状况下。如果这台服务器产生了物理故障、磁盘故障或者磁盘损坏等问题依然会产生数据失落。为了防止单点故障的问题、通常的做法就是将数据库复制多个正本部署在不同的服务器上、这样一台或者某几台服务器呈现故障、其它服务器仍能够对外提供数据。对此Redis为咱们提供了复制(replication)的性能、当一台数据库数据发生变化后将主动同步到其它的数据库中。Redis 的复制针对主从架构而设计的这里如果对主从架构还不太理解的倡议就先不要往下看了,花点半个小时去简略的理解下Redis 的主从架构模式。纵观 Redis 的主从复制原理咱们能够将其形象剥离成三个步骤进行了解。题外话、咱们在学习、了解干燥和乏味的算法或者技术原理时倡议大家先总体的过下流程之后将其形象成一个个简略的模型去了解、这样升高了学习和了解的难度。1. 主从(master < ---- > slave)之间建设连贯阶段。2. 数据同步(复制)阶段3. 命令流传阶段二、复制原理2.1 建设连贯阶段Redis 主从建设连贯阶段其实很简略,无非就是确认单方的身份建设连贯。和咱们➕某个心动女孩的微信统一。确认是本人喜爱的,想法设法的搞到微信号、发送好友申请、美眉确认、批准加好友、单方将微信号保留到彼此的好友列表中、彼此就建设起了分割。 间接上图吧! 2.2 数据同步阶段废话不多少间接上图干起 数据同步阶段Master的阐明 1、如果Master的数据量过大、数据同步阶段应避开流量顶峰阶段、防止造成Master的阻塞、影响失常业务的运行。2、复制缓冲区大小设置的不合理、会造成数据溢出。如果进行全量复制工夫过长、在进行局部复制时发现数据曾经失落的状况会进行二次全量复制(看下增量复制和全量复制的机会)、这样就导致Slave陷入一个死循环状态。repl-backlog-size: ??MB3、Master单机内存占主机内存不宜过大、倡议在50% - 70% 左右、留下 30 % - 50% 内存用于执行bgSave 和创立缓冲区。数据同步阶段Slave 的阐明 1、为了防止Slave在进行全量同步、局部(增量)同步阶段导致服务响应阻塞或者数据不同步、倡议敞开此期间对外提供服务。slave-server-stale-date: yes|no2、数据同步阶段 Master 向 Slave 发送信息能够了解为Master 是Slave的一个客户端、被动向Slave 发送命令。3、当多个Slave 同时向Master 发送数据同步申请时、发送的RDB文件增多、会对网络宽带造成微小冲击,如果Master网络宽带有余、倡议依据本身业务状况、适量错峰同步。4、Slave过多时倡议调整拓扑构造、由一主多从调整为树形构造、两头节点即是Master 也Slave 。留神当应用树形构造时因为层级深度、导致层级越深的节点和Master的数据提早越大、会导致肯定工夫内呈现数据一致性问题、应用时依据本身业务进行考量。2.3 命令流传阶段命令流传阶段就是为了实时保障主从数据统一的过程也就是数据同步过程。 当Master数据库状态被批改后,导致主从数据库状态不统一此时就须要让主从数据库的状态同步到统一的状态,同步的动作就称为命令流传。 Master 将接管到的数据变更命令会发送给Slave、Slave接管到命令后进行执行命令。 命令流传阶段的复制状况 - 命令流传阶段呈现断网状况 1. 网络闪断闪连: 疏忽 2. 短时间网络中断: 局部(增量)复制 3. 长时间网络中断: 全量复制 - 局部(增量)复制三要素 1. 服务器运行的ID(run id) 2. 主服务器的复制积压缓冲区(backlog) 3. 主从服务器复制的偏移量(offset)服务器运行ID: 概念: 服务器运行ID是每个Redis实列运行的惟一身份标识码、每次重启后服务器ID都会扭转。 组成:运行ID是由40位字符组成、是一个随机的十六进制的字符串。 作用:用于服务实列之间通信时的身份标识。 如果两次操作均对同一台服务器上的实列进行操作,则必须携带其运行runid 实现形式: 每台服务实列在启动时主动生成运行id、Master在首次连贯上Slave时会将本人的runid发送给Slave、Slave进行保留。能够通过 info server 命令来查看节点的runid。复制缓冲区:复制缓冲区又称为复制积压缓冲区、是一个先进先出的队列(backlog)。用于存储服务器执行过的命令、每次流传命令时主服务器都会将流传的命令记录下来并存储在复制缓冲区、并记录以后命令在缓冲区中的偏移量范畴。复制缓冲区默认存储空间的大小为1M当入队列元素的超过队列的长度会将队首的元素弹出并抛弃、新元素退出队列。作用: 保留Master接管到的所有执行(仅是影响数据状态变动的的指令set、select)的指令数据起源: Master 接管到客户端的指令时除了执行该指令还会将该指令保留到缓冲区。看图谈话 ...

April 29, 2021 · 1 min · jiezi

关于redis:oracle

1、数据定义语言(DDL ): Data Definition Language1、用于建设、批改、删除数据库对象。2、数据库对象包含:表、视图、索引、序列。 create 创立表或其余对象的构造alert 批改表或其余对象的构造drop 删除表或其余对象的构造2、数据操纵语言(DML): Data Manipulation Language用于扭转数据表中的数据。和事务相干,执行完后须要通过事务管制语句提交后能力真正的将扭转利用到数据库中。 insert 将数据插入到数据表中。update 更新数据表中已存在的数据delete 删除数据表中的数据3、事务管制语言(TCL): Transaction Control Language用来保护数据一致性的语句 COMMIT 提交,确认曾经进行的数据扭转ROLLBACK 回滚,勾销曾经进行的数据扭转SAVEPOINT 保留点,使以后的事务能够回退到指定的保留点,便于勾销局部扭转4、数据查询语言(DQL): Data Query Language用来查问所须要的的数据 select语句5、数据管制语言(DCL): Data Control Language用于执行权限的受权和发出操作 GRANT 授予,用于给用户或角色授予权限REVOKE 用于发出用户或角色已有的权限CREATE USER 创立用户数据类型 默认值都是为NULLNUMBER(p,s)p:示意数据的总位数s:示意小数点前面的位数例如:test NUMBER(6,2) 3333.33 CHAR固定长度,最大长度2000字节 VARCHAR可变动长度,最大长度4000字节 DATE 默认格局:DD-MON-RRSQL操作select * from table where 字段 like '%字%'; //含糊查问select * from table rownum=1; //查问一条select * from(select 字段,rownum rn from table) where rn>2; //查问大于2 rownum只有等于1成立,如需查问多条须要别名select * from table for update; //行级锁 其它用户只能查问但不能更新被加锁的数据行select * from table where name in('字段','字段'); //满足一条即可select * from table where 字段 is not null; //不等于空rownum等于1才成立大于1须要子查问和别名 ...

April 28, 2021 · 1 min · jiezi

关于redis:AOPRedis实现redis缓存

1.定义注解@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface AspectCache { String key(); /** * 定义工夫 * * @return 返回int */ int seconds() default 0; CACHE_TYPE cacheType() default CACHE_TYPE.FIND; enum CACHE_TYPE { FIND, UPDATE }}2.切面类@Aspect@Component@Slf4jpublic class CacheAspectConfig { private final RedisUtil redisUtil; @Autowired public CacheAspectConfig(RedisUtil redisUtil) { this.redisUtil = redisUtil; } @Around("@annotation(aspectCache)") public Object doAround(ProceedingJoinPoint joinPoint, AspectCache aspectCache) throws Throwable { return aroundMethod(joinPoint, aspectCache); } /** * @param joinPoint 连接点 * @param aspectCache 注解 * @return 返回object * @throws Throwable 异样 */ public Object aroundMethod(ProceedingJoinPoint joinPoint, AspectCache aspectCache) throws Throwable { String redisKey = aspectCache.key() + "::" + Arrays.toString(joinPoint.getArgs()); Object result = null; MethodSignature methodType = (MethodSignature) joinPoint.getSignature(); Class<?> returnType = methodType.getReturnType(); // 计时开始 log.info("-------------执行{}办法开始-----------", joinPoint.getSignature().getName()); Stopwatch started = Stopwatch.createStarted(); switch (aspectCache.cacheType()) { case FIND: // 查问缓存 result = findMethod(joinPoint, redisKey, returnType, aspectCache); break; case UPDATE: // 更新缓存 result = updateMethod(joinPoint, redisKey); break; default: result = findMethod(joinPoint, redisKey, returnType, aspectCache); break; } log.info("-------------执行:{}办法开始,所耗时:{}ms-----------", joinPoint.getSignature().getName(), started.stop()); return result; } /** * @param joinPoint 连接点 * @param key key * @param targetClass 类型 * @param aspectCache 注解对象 * @return object 返回数据 * @throws Throwable 抛出异样 */ private Object findMethod(ProceedingJoinPoint joinPoint, String key, Class<?> targetClass, AspectCache aspectCache) throws Throwable { Object result = null; if (redisUtil.hasKey(key)) { log.info("-----------缓存中有数据,从缓存中取------------"); String json = (String) redisUtil.get(key); result = JSON.toJavaObject(JSONObject.parseObject(json), targetClass); } else { log.info("-----------------查询数据库------------------"); result = joinPoint.proceed(); if (aspectCache.seconds() > ServiceConstants.INTEGER_ZERO) { redisUtil.set(key, JSONObject.toJSONString(result), aspectCache.seconds()); } else { redisUtil.set(key, JSONObject.toJSONString(result)); } } return result; } /** * 更新缓存 * * @param joinPoint 连接点 * @param key key * @return object * @throws Throwable 异样 */ private Object updateMethod(ProceedingJoinPoint joinPoint, String key) throws Throwable { log.info("--------------------删除缓存------------------"); redisUtil.del(key); return joinPoint.proceed(); }}

April 26, 2021 · 2 min · jiezi

关于redis:工作三年小胖连-Redis-持久化都不知道真丢人

00 前言很多小伙伴都用 Redis 做缓存,那如果 Redis 服务器宕机,内存中数据全副失落,应该如何做数据恢复呢?有人说很简略呀,间接从 MySQL 数据库再读回来就得了。 这种形式存在两个问题:一是频繁拜访 MySQL 数据库,有肯定的危险;二是慢,从界面上来看,从 MySQL 读就不如从 Redis 快。 远哥远哥,那咋办呀?教教我吧。 我用中指抵着小胖的下吧,说到:傻瓜,咱们能够做长久化呀。Redis 的长久化分两种,一种是 AOF,另一种是 RDB。来,坐哥哥腿上,我给你好好说道说道。 老规矩先上张脑图: 0.1 什么是长久化?长久化(Persistence),即把数据(如内存中的对象)保留到可永恒保留的存储设备中(如磁盘)。长久化的次要利用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML 数据文件中等等。长久化是将程序数据在长久状态和刹时状态间转换的机制。0.2 往期精彩1、小胖问我:select 语句是怎么执行的? 2、女朋友问我:MySQL 索引的原理是怎么的? 3、小胖问我:MySQL 日志到底有啥用? 4、老王问我:MySQL 事务与 MVCC 原理是怎么的? 5、女朋友问我:MySQL 的锁机制是怎么的? 6、万字长文,38 图爆肝 Redis 根底! 01 怎么了解 Redis 的单线程?必须申明一点:Redis 的单线程,是指 Redis 的网络 IO 和键值对读写是由一个线程(主线程)实现的,这也是 Redis 对外提供键值存储服务的次要流程。但 Redis 的其余性能,比方长久化、异步删除、集群数据同步等,其实是由额定的线程执行的。 1.0 Redis 快的起因?基于内存 数据都存储在内存里,缩小了一些不必要的 I/O 操作,操作速率很快。高效的数据结构 底层多种数据结构反对不同的数据类型,反对 Redis 存储不同的数据;不同数据结构的设计,使得数据存储工夫复杂度降到最低。正当的线程模型 I/O 多路复用模型同时监听多个客户端连贯;单线程在执行过程中不须要进行上下文切换,缩小了耗时。02 AOF 长久化AOF(Append Only File) 长久化是通过保留 Redis 服务器所执行的写命令来记录数据库状态,也就是每当 Redis 执行一个扭转数据集的命令时(比方 SET), 这个命令就会被追加到 AOF 文件的开端。 ...

April 26, 2021 · 3 min · jiezi

关于java:redisTemplate批量操作

1.redisTemplate的incr自增 public Integer incr(String key, Date expireDate) { key = getKey(key); RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); entityIdCounter.expireAt(expireDate); Long increment = entityIdCounter.incrementAndGet(); return increment.intValue(); }2.查问蕴含某字符的key列表scan操作 public Set<String> scan(String matchKey) { Set<String> keys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> { Set<String> keysTmp = new HashSet<>(); Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(matchKey + "*").count(1000).build()); while (cursor.hasNext()) { keysTmp.add(new String(cursor.next())); } return keysTmp; }); return keys; }3.批量查问key对应的值列表//批量查问缓存列表,返回值按顺序排列,在某个key不存在时,对应地位返回null public List<Integer> getMutiIncr(Collection<String> list) { if (CollectionUtils.isEmpty(list)){ return new ArrayList<>(); } ValueOperations ops = redisTemplate.opsForValue(); return ops.multiGet(list); }4.批量删除key列表对应的缓存 public void deleteBachKeysWithEnv(Collection<String> keys) { if (!CollectionUtils.isEmpty(keys)) { redisTemplate.delete(keys); } }5.key的指定hash构造通常存储map类型的数据,不适宜存有incr需要的数据key1:key2:key3构造的数据,不便读取https://www.jianshu.com/p/4c8... ...

April 25, 2021 · 1 min · jiezi

关于redis:Redis的复制基础篇系列四

Redis的主从复制篇来啦,本篇咱们来具体理解一下Redis的复制性能。 前言在分布式系统中为了解决单点问题,通常会把数据复制多个正本部署到其余机器,满足故障复原和负载平衡等需要。Redis也是如此,它为咱们提供了复制性能,实现了雷同数据的多个Redis正本。 Redis复制概述Redis复制是主机数据更新后依据配置和策略,主动会以异步复制的形式,同步数据到备机的机制;复制过程中并不会阻塞复制波及的Redis节点,他们都能持续解决其余命令的申请。其实复制实质上沿用了RDB长久化的流程,在主节点收到命令后执行bgsave生成RDB文件,而后将RDB文件送给另一个Redis节点应用。 参加复制的Redis实例划分为主节点(master)和从节点(slave)。默认状况下,Redis都是主节点。每个从节点只能有一个主节点,而主节点能够同时具备多个从节点。复制的数据流是单向的,只能由主节点复制到从节点。 因为复制波及到了主从节点的概念,所以也能够称为主从复制,然而,主从复制的概念和主从集群还是有些差异的,咱们下一篇集群中就会讲到主从集群。 Redis复制的用处(1)读写拆散:主节点提供写服务,从节点提供读服务;进步Redis服务器的并发量。(2)容灾复原:当主节点产生故障无奈服务,能够由从节点持续提供服务,实现故障的疾速复原。(3)数据冗余:主从复制实现了数据的热备份,是长久化之外的一种数据冗余形式。(4)高可用的基石:主从复制还是哨兵和主从集群可能施行的根底,因而说主从复制是Redis高可用的根底。 Redis主从复制操作开启主从复制,个别有以下三种形式: (1)配置文件中配置:slaveof masterip masterport在该配置文件中退出这个,指定成为谁的从机。(2)Redis服务启动时配置:redis-server redis.conf --slaveof masterip masterport;在服务启动的时候指定成为谁的从机。(3)Redis服务启动后通过客户端配置:slaveof masterip masterport:输出该命令后,本机成为从机,本机本来的数据也会不存在,跟主机的数据保持一致。 敞开主从复制:slaveof no one:使本机成为主数据库,也就完结了与其余数据库的同步。 Redis主从复制实现过程Redis主从复制过程大抵分为三个步骤: (1)连贯建设阶段:主从节点之间建设连贯,为数据同步做好筹备。(2)数据同步阶段:是主从复制最外围的阶段,依据主从节点以后状态的不同,能够分为全量复制和局部复制。(3)命令流传阶段:在这个阶段主节点将本人执行的写命令发送给从节点,从节点接管命令并执行,从而保障主从节点数据的一致性。 在本次例子中我应用了第三种形式创立主从复制,也就是连贯客户端后输出slaveof masterip masterport命令去复制,输出完这个命令后,Redis的日志如下,外面记录了在这之后具体产生了什么事件: 27962:S 23 Apr 12:09:11.774 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.#保留主节点的信息27962:S 23 Apr 12:09:11.776 * SLAVE OF 127.0.0.1:26379 enabled (user request from 'id=4 addr=127.0.0.1:26461 fd=7 name= age=43 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')#建设socket连贯27962:S 23 Apr 12:09:12.596 * Connecting to MASTER 127.0.0.1:2637927962:S 23 Apr 12:09:12.598 * MASTER <-> SLAVE sync started#通过ping命令检测socket连贯是否可用27962:S 23 Apr 12:09:12.598 * Non blocking connect for SYNC fired the event.27962:S 23 Apr 12:09:12.598 * Master replied to PING, replication can continue...27962:S 23 Apr 12:09:12.599 * Trying a partial resynchronization (request 21fa80655747f5e0448ae8449ebf7c61664304cb:1).27962:S 23 Apr 12:09:12.601 * Full resync from master: cc4cce78d7d21fe6d93ce00825db1274c8b256f1:460627962:S 23 Apr 12:09:12.601 * Discarding previously cached master state.#从机接管到来自主机的197比特的数据27962:S 23 Apr 12:09:12.731 * MASTER <-> SLAVE sync: receiving 197 bytes from master#从节点革除旧数据27962:S 23 Apr 12:09:12.731 * MASTER <-> SLAVE sync: Flushing old data#从节点把RDB中的数据载入内存27962:S 23 Apr 12:09:12.732 * MASTER <-> SLAVE sync: Loading DB in memory27962:S 23 Apr 12:09:12.732 * MASTER <-> SLAVE sync: Finished with success连贯建设阶段依据下面的日志能够看到,连贯建设也分为几个步骤:(1)保留主节点信息: ...

April 25, 2021 · 3 min · jiezi

关于redis:Redis持久化基础篇系列三

Redis的数据机构、CAP+BASE实践咱们在后面曾经理解过了,当初咱们来理解下Redis的长久化和事务。 前言在理论数据库选型过程中,为了灾备,可长久化根本是数据库的必要选项;Redis尽管是基于内存的,然而为了防止过程异常中断后数据的失落,也提供了两种长久化计划,将内存中的数据写入磁盘,尽量减少数据的失落。 Redis的长久化Redis 提供了两种长久化形式:RDB和AOF。 RDB长久化形式:可能在指定的工夫距离能对Redis的数据进行快照存储,造成一个dump.rdb文件;是 Redis 默认采纳的长久化形式。AOF长久化形式:记录每次对服务器写的操作,当服务器重启的时候会从新执行这些命令来复原原始的数据。 如果你只心愿你的数据在服务器运行的时候存在,你也能够不应用任何长久化形式。你也能够同时开启两种长久化形式,在这种状况下,当Redis重启的时候会优先载入AOF文件来复原原始的数据,因为在通常状况下AOF文件保留的数据集要比RDB文件保留的数据集要残缺。 RDB(Redis DataBase)RDB长久化形式:可能在指定的工夫距离能对Redis的数据进行快照存储,造成一个dump.rdb文件。 RDB快照的实现过程:(1)Redis会独自创立(fork)一个子过程来进行长久化,会先将以后内存中的数据写入到磁盘的一个临时文件中。(2)主过程是不进行任何IO操作,会持续接管并解决客户端发来的命令。(3)当子过程写入完所有数据后会用该临时文件替换旧的RDB文件,这样,一次RDB快照操作就实现了。 整个过程中,主过程是不进行任何IO操作的,这就确保了极高的性能。如果须要进行大规模数据的复原,且对于数据恢复的完整性不是十分敏感,那RDB形式要比AOF形式更加的高效。的毛病是 redis.conf的配置文件中,对于SNAPSHOTTING模块的全是RDB的相干配置。官网给出的配置文件中有这几种:save 900 1:若900S(15min)内数据库改变了一次,则触发快照条件。save 300 10:若300S(5min)内数据库改变了十次,则触发快照条件。save 60 10000:若60S(1min)内数据库改变了一万次,则触发快照条件。若不想应用长久化形式,能够配置成save ""。 总的来说,有以下四种触发快照条件:(1)达到配置文件中定义的规定(2)手动执行save或bgsave命令(3)执行flushall命令(4)执行主从复制操作的时候 save:执行save命令时Redis只管保留,其余不论,Redis进入阻塞状态。bgsave:Redis会在后盾异步进行快照操作,快照的同时还能够响应客户端申请。能够通过lastsave命令获取最初一次胜利执行快照的工夫。执行flushall命令,也会产生dump.rdb文件,但外面是空的,毫无意义。 注意事项: Redis 在进行快照的过程中不会批改原 RDB 文件,只有快照完结后才会将旧的文件替换成新的,也就是说任何时候 RDB 文件都是残缺的。这就使得咱们能够通过定时备份 RDB 文件来实现 Redis 数据库的备份, RDB 文件是通过压缩的二进制文件,占用的空间会小于内存中的数据,更加利于传输。RDB长久化形式复原数据:将RDB产生的备份文件(dump.rdb)挪动到Redis装置目录并启动Redis服务即可。 RDB的长处:(1)RDB是一个十分紧凑的文件,它保留了某个工夫点得数据集,十分实用于数据集的备份。(2)RDB是一个紧凑的繁多文件,很不便传送到另一个远端数据中心(可能加密),十分实用于劫难复原。(3)RDB在保留RDB文件时父过程惟一须要做的就是fork出一个子过程,接下来的工作全副由子过程来做,父过程不须要再做其余IO操作,所以RDB长久化形式能够最大化redis的性能。(4)与AOF相比,在复原大的数据集的时候,RDB形式会更快一些。 RDB的毛病: (1)RDB最初一次长久化后的数据可能失落。(2)如果你心愿在Redis意外进行工作(例如电源中断)的状况下失落的数据起码的话,那么RDB不适宜你。(3)RDB 须要常常fork子过程来保留数据集到硬盘上,当数据集比拟大的时候,fork的过程是十分耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的申请。如果数据集微小并且CPU性能不是很好的状况下,这种状况会继续1秒,AOF也须要fork,然而你能够调节重写日志文件的频率来进步数据集的耐久度。 AOF(Appendonly File)AOF长久化形式用日志的模式记录每次对服务器写的操作,当服务重启的时候会从新执行这些命令来复原原始的数据,AOF的命令以Redis协定追加保留每次写的操作到文件开端。Redis还能对AOF文件进行后盾重写,使得AOF文件的体积不至于过大。 redis.conf的配置文件中,对于APPEND ONLY MODE模块的全是AOF的相干配置。官网给出的配置文件中默认是不开启的:appendonly no:想要开启AOF长久化形式,批改成yes即可。 appendfsync always:同步长久化,每次产生数据变更会立刻记录到磁盘,性能较差但数据完整性比拟好。appendfsync everysec:默认配置,异步操作,每秒记录数据变更;如果产生宕机最多失落一秒的数据。appendfsync no:从不被动同步。 AOF长久化形式复原数据:AOF会产生文件(appendonly.aof),Redis启动时会从新执行这些命令来复原原始的数据。 AOF重写因为 AOF 的运作形式是一直地将命令追加到文件的开端, 所以随着写入命令的一直减少, AOF 文件的体积也会变得越来越大。举个例子, 如果你对一个计数器调用了 100 次 INCR key, 那么仅仅是为了保留这个计数器的以后值, AOF 文件就须要应用 100 条记录(entry)。然而在实际上, 只应用一条 SET key value [EX seconds] [PX milliseconds] [NX|XX]命令曾经足以保留计数器的以后值了, 其余 99 条记录实际上都是多余的。 ...

April 25, 2021 · 1 min · jiezi

关于node.js:nodejs轻量级框架Koa2实现session功能

写在后面,这里不对koa2做介绍,次要介绍一下koa2实现session性能。 入口文件app.jsconst Koa = require('koa') // v2.7.0const app = new Koa()const json = require('koa-json')const bodyparser = require('koa-bodyparser')const session = require('koa-generic-session') // v2.1.1const redisStore = require('koa-redis') // v4.0.1// routerconst user = require('./routes/user')app.use(user.routes(), user.allowedMethods())// 解析request bodyapp.use(bodyparser({ enableTypes:['json', 'form', 'text']}))app.use(json())//session 配置 次要看这里!!!app.keys = ['abc123'] // 加密cookie用,能够随便写一个stringapp.use(session({ cookie: { path: '/', // 我的项目根门路,示意cookie用于整个我的项目 httpOnly: true, // 禁止客户端通过js脚本批改cookie maxAge: 24 * 60 * 60 * 1000 // cookie过期工夫 这里设置1天 }, // 配置redis store: redisStore({ all: '127.0.0.1:6379' // 这里用本地redis服务,默认端口6379 })}))module.exports = app这样就配置好了,接下来咱们写一个路由进行测试,在routers/user.js中写入以下代码: ...

April 25, 2021 · 1 min · jiezi

关于后端:Redis分布式理论基础篇系列二

Redis的一些特点和数据结构咱们在上一篇中曾经理解到了,那么这篇咱们来理解一下分布式实践CAP+BASE。 前言说Redis,那么Redis跟CAP和BASE实践有什么关系呢?那是因为CAP和BASE实践是Redis、MongoDB等泛滥NoSQL数据库管理系统的实践根底;而ACID才是传统关系型数据库的设计理念,ACID 和 BASE代表截然不同的两种设计哲学,强一致性-可用性的两端。 CAP实践CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个 分布式计算零碎 来说,不可能同时满足以下三点: Consistency(一致性): 所有节点在同一时间具备雷同的数据Availability(可用性):保障每个申请不论胜利或者失败都有响应(也就是只有收到用户的申请,服务器都要在正当的工夫内给出正当的响应)Partition tolerance(分区容错):零碎中任意信息的失落或失败不会影响零碎的持续运作(也就是分布式系统遇到任何网络分区故障时,依然能够对外提供一致性、可用性的服务) 上面咱们来具体理解一下这三个准则:C:Consistency(一致性)在分布式环境中,一致性是指数据在多个正本之间是否可能保持一致的个性(这点跟ACID中的一致性含意不同)。对于一个将数据正本散布在不同节点上的分布式系统来说,如果对第一个节点的数据进行了更新操作并且更新胜利后,却没有使得第二个节点上的数据失去相应的更新,于是在对第二个节点的数据进行读取操作时,获取的仍然是更新前的数据(称为脏数据),这就是典型的分布式数据不统一状况。在分布式系统中,如果可能做到针对一个数据项的更新操作执行胜利后,所有的用户都能读取到最新的值,那么这样的零碎就被认为具备强一致性(或严格的一致性)。 A:Availability(可用性)可用性是指零碎提供的服务必须始终处于可用的状态,对于用户的每一个操作申请总是可能在无限的工夫内返回后果,如果超过了这个工夫范畴,那么零碎就被认为是不可用的。『无限的工夫内』是一个在零碎设计之初就设定好的运行指标,不同的零碎会有很大的差异。比方对于一个在线搜索引擎来说,通常在0.5秒内须要给出用户搜寻关键词对应的检索后果。而对应Hive来说,一次失常的查问工夫可能在20秒到30秒之间。『返回后果』是可用性的另一个十分重要的指标,它要求零碎在实现对用户申请的解决后,返回一个失常的响应后果。失常的响应后果通常可能明确地反映出对申请的处理结果,及胜利或失败,而不是一个让用户感到困惑的返回后果。让咱们再来看看下面提到的在线搜索引擎的例子,如果用户输出指定的搜寻关键词后,返回的后果是一个零碎谬误,比方"OutOfMemoryErroe"或"System Has Crashed"等提醒语,那么咱们认为此时零碎是不可用的。 P:Partition tolerance(分区容错性) 分区容错性要求一个分布式系统须要具备如下个性:分布式系统在遇到任何网络分区故障的时候,依然可能保障对外提供满足一致性或可用性的服务,除非是整个网络环境都产生了故障。网络分区是指在分布式系统中,不同的节点散布在不同的子网络(机房或异地网络等)中,因为一些非凡的起因导致这些子网络之间呈现网络不连通的情况,但各个子网络的外部网络是失常的,从而导致整个零碎的网络环境被切分成了若干个孤立的区域。 CAP实践的外围是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需要,最多只能同时较好的满足两个。因而,依据CAP原理将NoSQL数据库分成了满足CA准则、满足CP准则和满足AP准则三大类:CA - 单点集群,满足一致性,可用性的零碎,通常在可扩展性上不太强大。比方传统的Oracle数据库。CP - 满足一致性,分区容错性的零碎,通常性能不是特地高。比方Redis、MongoDB。AP - 满足可用性,分区容错性的零碎,通常可能对一致性的要求低一些,满足最终一致性即可。大多数网站架构的抉择。 CAP实践提出就是针对分布式数据库环境的,所以,P这个属性是必须具备的;那么这时候C和A能同时满足吗?答案是不能的:Consistency 和 Availability 的矛盾一致性和可用性,为什么不可能同时成立?答案很简略,因为可能通信失败(即呈现分区容错)。 假如数据库一和数据库二同时为客户端服务,这两个库的数据是统一的。 如果保障 数据库二 的一致性,那么数据库一必须在写操作时,锁定 数据库二 的读操作和写操作。只有数据同步后,能力从新凋谢读写。锁定期间,数据库二 不能读写,没有可用性不。如果保障 数据库二 的可用性,那么势必不能锁定 数据库二,所以一致性不成立。综上所述,数据库二 无奈同时做到一致性和可用性。零碎设计时只能抉择一个指标。如果谋求一致性,那么无奈保障所有节点的可用性;如果谋求所有节点的可用性,那就没法做到一致性。 综上所述,因为网络的起因,必定会呈现提早和丢包等问题,所以:分区容错性(Partition tolerance)是咱们必须要实现的。所以只能在一致性和可用性之间进行衡量,没有NoSQL零碎能同时保障这三点。 BASE实践BASE是Basically Available(根本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写。BASE是对CAP中一致性和可用性衡量的后果,其来源于对大规模互联网零碎分布式实际的总结,是基于CAP定理逐渐演变而来的,其核心思想是即便无奈做到强一致性,但每个利用都能够依据本身的业务特点,采纳适当的办法来使零碎达到最终一致性。接下来,咱们着重对BASE中的三要素进行解说。 根本可用根本可用是指分布式系统在呈现不可预知故障的时候,容许损失局部可用性——但请留神,这绝不等价于零碎不可用。以下举例两个"根本可用"的例子: (1)响应工夫上的损失:失常状况下,一个在线搜索引擎须要在0.5秒之内返回给用户相应的查问后果,但因为呈现故障(比方零碎局部机房产生断电或断网故障),查问后果的响应工夫减少到了1-2秒。 (2)性能上的损失:失常状况下,在电商平台上购物,消费者齐全可能顺利地实现每一笔订单。但在双十一期间,因为消费者的购物行为激增,为了爱护系统核心性能的可用性,通常会采取服务降级的策略,比方敞开评论等非核心性能。 软状态软状态是指容许零碎中的数据存在中间状态,并认为该中间状态的存在不会影响零碎的整体可用性,即容许零碎在不同的数据正本之间进行数据同步的过程存在延时。 最终一致性最终一致性强调的是零碎中所有的数据正本,在通过一段时间的同步后,最终可能达到一个统一的状态。因而,最终一致性的实质是须要零碎保障最终数据可能达到统一,而不须要实时保证系统数据的强一致性。 最终一致性是一种非凡的弱一致性:零碎可能保障在没有其余新的更新操作的状况下,数据最终肯定可能达到统一的状态,因而所有客户端对系统的数据拜访都可能获取到最新的值。同时,在没有产生故障的前提下,数据达到统一状态的时间延迟,取决于网络提早、零碎负载和数据复制方案设计等因素。 在理论工程实际中,最终一致性存在以下五类次要变种:(1)因果一致性(Causal consistency)(2)读己之所写(Read your writes)(3)会话一致性(Session consistency)(4)枯燥读一致性(Monotonic read consistency)(5)枯燥写一致性(Monotonic write consistency) 以上就是最终一致性的五种常见的变种,在理论零碎实际中,能够将其中的若干个变种相互联合起来,以构建一个具备最终一致性个性的分布式系统。事实上,最终一致性并不是只有那些大型分布式系统才波及的个性,许多古代的关系型数据库都采纳了最终一致性模型。在古代关系型数据库中(比方MySQL和PostgreSQL),大多都会采纳同步或异步形式来实现主备数据复制技术。在同步形式中,数据的复制过程通常是更新事务的一部分,因而在事务实现后,主备数据库的数据就会达到统一。而在异步形式中,备库的更新往往会存在延时,这取决于事务日志在主备数据库之间传输的工夫长短。如果传输工夫过长或者甚至在日志传输过程中出现异常导致无奈及时将事务利用到备库上,那么很显然,从备库中读取的数据将是旧的,因而就呈现了数据不统一的状况。当然,无论是采纳多次重试还是人为数据勘误,关系型数据库还是可能保障最终数据达到统一,这就是零碎提供最终一致性保障的经典案例。 总的来说,BASE实践面向的是大型高可用可扩大的分布式系统,和传统事务的ACID个性使相同的,它齐全不同于ACID的强一致性模型,而是提出通过就义强一致性来取得可用性,并容许数据在一段时间内是不统一的,但最终达到统一状态。但同时,在理论的分布式场景中,不同业务单元和组件对数据一致性的要求是不同的,因而在具体的分布式系统架构设计过程中,ACID个性与BASE实践往往又会联合在一起应用。

April 25, 2021 · 1 min · jiezi

关于idea:还在苦苦寻找IDEA破解吗还在发愁外网下载工具太慢吗那就看过来乐字节整理的10G编程开发常用工具包

有很多软件都是外国的,在国内下载切实太慢了。有什么方法能搞定这个问题呢?上面请看乐字节教育流出的编程开发罕用工具包 先看一眼大略的工具有那些 IDEA是 Java 语言开发的集成环境,IDEA 在业界被公认为最好的 Java 开发工具之一,然而免费的软件,对应咱们这些穷小子来说,是个坏消息。所有咱们有中国魔法。 一些罕用编辑器都放在IDEA开发工具包里 IDEA比拟新的版本包含破解步骤都在这里 轻轻松松给它干到2089年,到那个时候你的工资足够付的几十个甚至几百个IDEA的钱了,先用着等有钱再还给它 Java版本,jdk8,也是Java遍及最快的版本,除了自身性能晋升外,新增的函数式编程个性也让开发效率更高,举荐应用。包含一些公司罕用的和新的jdk版本也在这里(地位:常用工具\常用工具\jdk) web容器,tomcat,也是微服务项目首选容器。Nginx (engine x) 是一个高性能的和web服务器。 (地位:常用工具\常用工具\服务器) 第三方中间件和插件,包含:dubbo,redis,mycat等等(地位:常用工具\常用工具\第三方中间件) 还有一些乐字节老师用过比拟好用的编程人员用到的工具包 一些罕用的数据库 其余的工具包小编就不一一介绍了,基本上你在学习Java的时候能用到的货色都在这个包里,不再放心下载到一堆的广告软件,也不必放心外网下载慢了。 感激乐字节分享所有的工具包。 须要的同学们sx我哦!!!! 或者扣1哦!!!

April 23, 2021 · 1 min · jiezi

关于spring:五整合redisrestful接前后端分离进行登录验证和url鉴权

应用jwt token来认证和鉴权<!--jwt配置文件--><dependency> <groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency> (jwt也可,只须要将userDto的信息应用jwt来保留即可返回时,返回jwt的字符串,我这是将用户信息保留在了redis中) 1、配置security文件 /** SpringSecurity的配置Created by wenye on 2021/4/12. */@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled=true)public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowiredprivate RestfulAccessDeniedHandler restfulAccessDeniedHandler;@Autowiredprivate RestAuthenticationEntryPoint restAuthenticationEntryPoint;// 下面是登录认证相干 上面为url权限相干 - ========================================================================================/** * 获取拜访url所须要的角色信息 */@Autowiredprivate UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;/** * 认证权限解决 - 将下面所取得角色权限与以后登录用户的角色做比照,如果蕴含其中一个角色即可失常拜访 */@Autowiredprivate UrlAccessDecisionManager urlAccessDecisionManager;/** * 自定义拜访无权限接口时403响应内容 */@Autowiredprivate UrlAccessDeniedHandler urlAccessDeniedHandler;@Autowiredprivate MyuserDetailsService userDetailsService;//申请权限配置@Overrideprotected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/login/user/employee/login", "/login/user/employee/register")// 对登录注册要容许匿名拜访 .permitAll() .antMatchers(HttpMethod.OPTIONS)//跨域申请会先进行一次options申请 .permitAll() .authenticated(); ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests(); registry.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { @Override public <O extends FilterSecurityInterceptor> O postProcess(O o) { o.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource); o.setAccessDecisionManager(urlAccessDecisionManager); return o; } }); // 增加JWT filter http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); //增加自定义未受权和未登录后果返回 http.exceptionHandling() .accessDeniedHandler(restfulAccessDeniedHandler) .authenticationEntryPoint(restAuthenticationEntryPoint);}@Beanpublic JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() { return new JwtAuthenticationTokenFilter();}/* 能够不要哦 ...

April 23, 2021 · 4 min · jiezi

关于redis:万字长文38-图爆肝-Redis-基础

00 前言Redis 在互联网技术存储方面的应用能够说是十分宽泛了,只有是接触过 Java 开发的敌人就算你没用过,都会听过它。在面试也是十分高频的一个知识点。 最近,我的的小弟小胖和老王就对 Redis 十分感兴趣;我举荐它一本书《Redis设计与实现》。谁知这货说看不下去,非要我来总结一波。所以本文算是给小胖和老王的学习材料,也是我本人的学习笔记。心愿对你有帮忙。 还是老规矩,先上张脑图。全文 13274 字,从下午 2 点爆肝到早晨 9 点,先上张思维导图镇楼: 0.1 往期精彩1、小胖问我:select 语句是怎么执行的? 2、女朋友问我:MySQL 索引的原理是怎么的? 3、小胖问我:MySQL 日志到底有啥用? 4、老王问我:MySQL 事务与 MVCC 原理是怎么的? 5、女朋友问我:MySQL 的锁机制是怎么的? 01 什么是 Redis?官网是这么形容的: Redis (用 C 语言实现的)是一个开源的,基于内存的数据结构存储,可用作于数据库、缓存、消息中间件。信息简洁明了,一下就晓得了三个点:基于内存、用作缓存、多种数据结构。 的了,那就从这三个方面开始钻研呗。 1.0 为什么要用 Redis 做缓存?下面说了,用作缓存。有些小伙伴可能会问:有 MySQL 数据库就得了呗?干嘛还要缓存?而且为啥要用 Redis 做?Map 不行嘛? 第一、二个问题,都晓得 MySQL 数据是存在磁盘的,而 CPU 拜访磁盘是十分慢的。如果遇到并发高的时候,所有线程每次都要拜访磁盘,预计得挂。到底有多慢?请看链接:zhuanlan.zhihu.com/p/24726196 Redis 和 Map 做下比照,就晓得为啥不适合了。 Map 是本地缓存,如果在多台机器部署,必须每个机器都要复制一份,否则造成缓存不统一;Redis 是分布式缓存,部署在多台机器,也是用的同一份缓存,放弃了一致性,问题不大。Map 做缓存,数据量大的话会导致 JVM 内存飙升,进而拖垮程序,并且 JVM 挂了,还会导致数据失落;Redis 能够用更大容量的内存(看你的配置,即几十G都没问题)做缓存,并且还能够长久化到磁盘。02 Redis 的数据结构你可能第一反馈不就 "String(字符串)、List(列表)、Hash(哈希)、Set(汇合)和 Sorted Set(有序汇合)么?",太简略了,我都会。 ...

April 21, 2021 · 7 min · jiezi

关于jedis:干货丨Redis常见客户端异常汇总Jedis篇

转自@twt社区,作者:付磊。 【导读】Jedis是Redis的java版本的客户端实现。在Redis客户端的应用过程中,无论是客户端使用不当或者Redis服务端呈现问题,客户端会反馈出一些异样,本文剖析了Jedis应用过程中常见的异常情况。 一、无奈从连接池获取到连贯 JedisPool中的Jedis对象个数是无限的,默认是8个。这里假如应用的默认配置,如果有8个Jedis对象被占用,并且没有偿还,如果调用者还要从JedisPool中借用Jedis,就须要进行期待(例如设置了maxWaitMillis>0),如果在maxWaitMillis工夫内依然无奈获取到Jedis对象就会抛出如下异样。 redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool …Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)还有一种状况,就是设置了blockWhenExhausted=false,那么调用者发现池子中没有资源时,会立刻抛出异样不进行期待,上面的异样就是blockWhenExhausted=false时的成果。 redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool …Caused by: java.util.NoSuchElementException: Pool exhausted at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)对于这个问题,须要重点探讨的是为什么连接池没有资源了,造成没有资源的可能的起因十分多 1.客户端:高并发下连接池设置过小,呈现供不应求,所以会呈现下面的谬误,然而失常状况下只有比默认的最大连接数(8个)多一些即可,因为失常状况下JedisPool以及Jedis的解决效率足够高。 2.客户端:没有正确应用连接池,比方没有进行开释,例如上面代码所示:定义JedisPool,应用默认的连接池配置。 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);//向JedisPool借用8次连贯,然而没有执行偿还操作。for (int i = 0; i < 8; i++) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.ping(); } catch (Exception e) { e.printStackTrace(); }}当调用者再向连接池借用Jedis时(如下操作),就会抛出异样: ...

April 20, 2021 · 1 min · jiezi

关于数据库:华为云PB级数据库GaussDBfor-Redis揭秘第八期用高斯-Redis-进行计数

摘要:高斯Redis,计数的最佳抉择!本文分享自华为云社区《华为云PB级数据库GaussDB(for Redis)揭秘第八期:用高斯 Redis 进行计数》,原文作者:神思胖。 一、背景当咱们关上手机刷微博时,就要开始和各种各样的计数器打交道了。咱们注册一个帐号后,微博就会给咱们记录一组数据:关注数、粉丝数、动静数…;咱们刷帖时,关注每天的热搜状况,微博须要为每个热搜记录一组搜寻量。在这一串数据前面,是一个个计数器在工作。 计数器能够分为惯例计数器和基数计数器,对于惯例计数器,只须要对计数器进行简略的增减即可;对于基数计数器,须要对元素进行去重,比方统计搜寻量时,须要保障每个用户的屡次搜寻只统计一次。对于这两种需要,Redis 都有对应的数据类型进行统计。然而开源 Redis 是一个弱一致性的数据库,在特定的场景下,弱统一的计数不能满足业务需要,为此,咱们须要一个强统一的数据库进行计数。 GaussDB(for Redis)(下文简称高斯Redis),是华为自研的强统一、长久化 NoSQL 数据库,兼容 Redis5.0 协定。本文将介绍惯例计数器与基数计数器的利用场景及应用高斯 Redis 实现计数。 二、惯例计数器2.1如何应用 Redis 进行惯例计数Redis 实现惯例计数器有两种数据类型适宜:String 和 Hash。 2.1.1应用string 计数当咱们须要保护的计数器数目较少,比方统计网站的注册用户数时,适宜应用 String 类型的计数器。Redis 提供的 Incr 和 Decr 命令别离对 String 类型的 key 值进行增一与减一操作: 127.0.0.1:6379> SET counter 100OK127.0.0.1:6379> INCR counter(integer) 101127.0.0.1:6379> DECR counter(integer) 100除Incr与Decr命令外,Redis String 类型还提供 Incrby 与 Decrby 命令,语法格局为: incrby: INCRBY key count将 key 减少 count,count 可正可负,返回 key 的后果: 127.0.0.1:6379> INCRBY counter 10(integer) 10127.0.0.1:6379> INCRBY counter -20(integer) -10decrby: DECRBY key count将 key 缩小 count,count 可正可负,返回 key 的后果: ...

April 20, 2021 · 2 min · jiezi

关于redis:Redis哨兵机制全面深入分析与讲解实战演示篇

文章简介本文将通过实践+实际的形式从头到尾总结Redis中的哨兵机制。文章内容从主从复制的弊病、如何解决弊病、什么是哨兵、哨兵监控的图形构造、哨兵监控的原理、如何配置哨兵、哨兵与主从复制的关系等方面来演示。 文中相干材料下载地址:链接: https://pan.baidu.com/s/1cDV9... 明码: mv86 主从复制弊病 下面的图形构造,大抵的能够了解为Redis的主从复制拓扑图。 其中1个主节点负责利用零碎的写入数据,另外的4个从节点负责利用零碎的读数据。同时4个从节点向其中的1个一个主节点发动复制申请操作。在Redis服务运行失常的状况下,该拓扑结构造不会呈现什么问题。试想一下这样的一个场景。如果主节点服务产生了异样,不能失常解决服务(如写入数据、主从复制操作)。这时候,Redis服务能失常响应利用零碎的读操作,然而没法进行写操作。 呈现该状况就会重大影响到零碎的业务数据。那该如何解决呢? 能够大抵想到上面的几种状况来解决。 当主节点产生异常情况时,手动的从局部从节点中抉择一个节点作为主节点。而后扭转其余从节点的主从复制关系。咱们也能够写一套主动解决该状况的服务,防止依赖于人为的操作。下面的计划在肯定水平上是能帮忙咱们解决问题。然而过多的人为干涉。例如第1点,咱们须要思考人工解决的实时性和正确性。第2点,自动化解决是可能很好的解决第1点中的问题,然而主动解决存在如何抉择新主节点的问题,因而这也是一个不好的中央。 通过下面大抵的剖析,咱们不难得出Redis的哨兵机制就是针对种种问题呈现的。 什么是哨兵能够把Redis的哨兵了解为一种Redis分布式架构。 该架构中次要存在两种角色,一种是哨兵,另外一种是数据节点(主从复制节点)。 哨兵次要负责的工作是: 每一个哨兵都会监控数据节点以及其余的哨兵节点。当其中的一个哨兵监控到节点不可达是,会给对应的节点做下线标识。如果下线的节点为主节点。这时候会告诉其余的哨兵节点。哨兵节点通过“协商”推举出从节点中的某一个节点为主节点。接着将其余的从节点断开与旧主节点的复制关系,将推举进去的新主节点作为从节点的主节点。将切换的后果告诉给利用零碎。 配置哨兵在演示环境中,配置了三台数据节点(1主2从),三台哨兵节点。演示中用到的Redis为6.0.8版本。 角色IP端口号(数据节点)master127.0.0.18002(数据节点)slave127.0.0.18003(数据节点)slave127.0.0.18004哨兵节点127.0.0.18005哨兵节点127.0.0.18006哨兵节点127.0.0.18007(数据节点)master配置。# 服务配置daemonize yes# 端口号port 8002# 数据目录dir "/Users/kert/config/redis/8002"# 日志文件名称logfile "8002.log"# 设置明码bind 0.0.0.0# requirepass 8002# 多线程# 1.开启线程数。io-threads 2# 2.开启读线程。io-threads-do-reads yes# 长久化存储(RDB)# 1.每多少秒至多有多少个key发生变化,则执行save命令。save 10 1save 20 1save 30 1# 2.当bgsave命令产生谬误时,进行写入操作。stop-writes-on-bgsave-error yes# 3.是否开启rbd文件压缩rdbcompression yes(数据节点)slave配置。# 服务配置daemonize yesport 8004dir "/Users/kert/config/redis/8004"logfile "8004.log"# 多线程# 1.开启线程数。io-threads 2# 2.开启读线程。io-threads-do-reads yes# 长久化存储(RDB)# 1.每多少秒至多有多少个key发生变化,则执行save命令。save 10 1save 20 1save 30 1# 2.当bgsave命令产生谬误时,进行写入操作。stop-writes-on-bgsave-error yes# 3.是否开启rbd文件压缩rdbcompression yes# 配置主节点信息replicaof 127.0.0.1 8002哨兵节点配置。# 端口号port 8006# 运行模式daemonize yes# 数据目录dir "/Users/kert/config/redis/sentinel/8006"# 日志文件logfile "8006.log"# 监听数据节点sentinel monitor mymaster 127.0.0.1 8002 2(断定主节点下线状态的票数)# 设置主节点连贯权限信息sentinel auth-pass mymaster 8002# 判断数据节点和sentinel节点多少毫秒数内没有响应ping,则解决为下线状态sentinel down-after-milliseconds mymaster 30000# 主节点下线后,从节点向新的主节点发动复制的个数限度(指的一次同时容许几个从节点)。sentinel parallel-syncs mymaster 1# 故障转移超时工夫sentinel failover-timeout mymaster 180000所有的哨兵节点间接将port、dir和logfile批改为对应的具体哨兵信息即可。接着启动对应的服务Redis服务。 ...

April 18, 2021 · 4 min · jiezi

关于redis:springboot整合redis的发布订阅

@Configurationpublic class RedisMessageConfig { @Beanpublic RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter){ RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listenerAdapter,new PatternTopic("mytopic")); return container;}@Beanpublic MessageListenerAdapter listenerAdapter() { return new MessageListenerAdapter(new Receiver(), "receiveMessage");}} @Slf4jpublic class Receiver { public void receiveMessage(String message) { log.info("Received <" + message + ">");}} 其中"mytopic"相当于redis外面的channel频道, 客户端始终在监听这个频道。关上redis客户端, 忘channel发送音讯,留神返回值,返回值0代表没有监听者接管到音讯,如果接管到音讯则返回1 客户端接管到公布的音讯 目前测试这个公布订阅遇到的坑点 springboot整合的redis监听器老是过一段时间的生效而接管不到音讯由下面的起因 造成音讯失落

April 18, 2021 · 1 min · jiezi

关于java:我所知道Reids之Windows系统搭建集群

前言公司我的项目有应用Reids进行缓存搭建,然而对于本机电脑并没有搭建对应的环境 所以防止每次反复搭建环境,同时记录相应的步骤与一些坑。避免浪费工夫与精力 一、Reids环境搭建下载redis最新版本(版本必须要3.0以上)================================ Redis cluster(redis集群)是在版本3.0后才反对的架构,和其余集群一样,都是为了解决单台服务器不够用的状况,也避免了主服务器宕机无备用服务器,多个节点网络互联数据共享,所有节点都是一主一从(也能够一主多从) 情谊举荐:下载 Redis-x64-3.2.100.zip 可装置在C盘中:下载地址 二、集群的筹备工作配置节点信息================================ 在redis目录下创立6个节点的文件夹:7001-7006 也能够应用cmd命令进行创立 将redis上面的文件复制到7001节点文件夹上面(其余700x的也是这样操作) 批改这六个文件夹下redis.windows.conf 文件配置 这时咱们在每个节点目录下创立start.bat来启动redis内容如下(端口记得对应): title redis-7001redis-server.exe redis.windows.conf 配置Ruby语言环境================================ 咱们采纳Reids提供的 redis-trib.rb工具来搭建集群,须要配置环境:下载地址 应用命令校验是否装置胜利,并且查看咱们的gem源是什么版本(举荐与Redis差不多) 同时启动后,装置配置Redis 插件 三、开始配置集群环境下载安装集群脚本 redis-trib.rb 此时咱们将Reids公共的集群脚本放入咱们装置的Reids的目录下,获取地址(验证码:2fe5) 此时咱们将创立的7001-7006节点别离执行启动起来 redis-server.exe redis.windows.conf 此时将7001-7006都启动之后,在reids根目录下进行配置 窗口输出以下命令进行配置,留神端口信息要开启运行起来 redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 在呈现 Can I set the above configuration? (type 'yes' to accept): 请确定并输出 yes 。 四、测试集群环境在其中一个节点的目录下咱们set一个key进行看看 ...

April 17, 2021 · 1 min · jiezi

关于redis:Redis知识点梳理总结

[TOC] 1. Redis简介 redis全称 Remote Dictionary Service(近程字典服务)。Redis存储的都是K-V对,Redis里寄存的任何一条数据都有惟一的key作为名称。Redis中,所有的key都存储在一个很大的字典中。一个Redis实例有多个库(database),可用过配置文件里的“databases”配置,库索引从0到databases-1,能够应用指令SELECT <index>切换到不通的库。 留神:在Redis命令行,Redis的指令不辨别大小写,然而key辨别大小写。 2. Redis根底数据结构 Redis有五种根底的数据结构:string、list、hash、set、zset。其中list、hash、set、zset称为容器型数据结构,容器型数据结构有两条通用规定: 如果容器不存在,就创立一个,再进行操作。如果容器里没有数据了,就立刻删除,回收内存。2.1 string(字符串)string是Redis最简略的数据结构,一个key对应一个value。Redis的string实际上是应用数组实现的。 string根本指令有: SET:设置一个kv对,示例:SET name lilyGET:获取一个key对应的的value,示例:GET nameMSET:设置一个或多个kv对,示例:MSET name lily age 18MGET:获取一个或多个key对应的value,示例:MGET name ageSETNX:设置一个kv对,如果该key不存在,设置胜利;如果改成存在,设置失败,示例:SETNX name lileiINCR:如果 value 是整数,还能够进行原子加一操作,示例:INCR ageDECR:如果 value 是整数,还能够进行原子减一操作,示例:DECR age2.2 list(列表) Redis的list是链表实现的,所以其插入删除操作十分快,工夫复杂度都是O(1),然而索引定位很慢,工夫复杂度是O(n)。当list中没有元素了,该数据结构会主动删除,内存被回收。 list的根本指令有: LPUSH:从右边插入元素,能够插入多个。示例:LPUSH students lily lilei zhangsanLPOP:从右边删除元素,默认删除一个元素。能够指定须要删除的个数,示例:LPOP students 5RPUSH:从左边插入元素,用法同LPUSHRPOP:从左边删除元素,用法同LPOPLRANGE:列出指定范畴里的元素(不会删除元素),示例:LRANGE students 0 -1LINDEX:(工夫复杂度O(n))获取指定地位的元素,示例:LINDEX students 1LTRIM:(工夫复杂度O(n))删除指定范畴的元素,示例:LTRIM students 1 2list罕用场景: 队列/音讯队列 从list的一边push数据,从另一边pop数据,就能够作为队列或者音讯队列应用。如果list外面没有数据,LPOP和RPOP不会阻塞,都会立刻返回空。如果用作音讯队列,消费者须要解决LPOP或RPOP立刻返回空的状况,个别的做法是如果返回为空,期待一段时间,再次获取,然而等待时间不好确定,等待时间太短会拉高CPU,造成节约;等待时间太长会升高QPS,影响性能。Redis为list设计了阻塞读指令:BLPOP、BRPOP,指令用法是BLPOP key1 [key2 ...] timeout,这里BLPOP/BRPOP里的B是blocking的意思。阻塞读在list没有数据的时候,会立刻休眠,一旦有数据到了,则立即醒过来。 栈 在list的同一边push和pop数据,就能够作为栈应用 音讯队列 LPOP或者RPOP操作不会阻塞,如果list外面没有数据,LPOP和RPOP都会立刻返回空,如果 2.3 hash(字典) Redis的hash的值只能是字符串。 hash的根本指令: HMSET:写入数据,反对批量。示例: HMSET 001 name lily age 18,其中 001 是该条hash的key,name、age 是hash外面的field。HMGET:获取指定hash的某个field的value。示例:HMGET 001 nameHGETALL:获取指定hash的所有数据。示例:HGETALL 001 HINCRBY :如果hash外部的value是整型,能够应用HINCRBY进行原子加减操作(只需讲操作数设置为正数就是减法操作),示例:HINCRBY 001 age 1,HINCRBY 001 age -12.4 set(汇合) Redis的set是无序的。 ...

April 16, 2021 · 4 min · jiezi

关于redis集群:Redis哨兵集群搭建

1、筹备工作哨兵节点的搭建起码须要3个节点、在开始之前咱们须要先来搭建一个主从集群(一主两从)具体搭建步骤请查看https://segmentfault.com/a/1190000039261382 2、配置哨兵哨兵的默认端口为26397、默认端口不能和其余机器指定的端口连通,只能在本地拜访。在这里咱们应用端口5000(能够依据本人的状况定)。 2.1 创立相应的文件夹#寄存哨兵配置文件mkdir /etc/sentinel#存放数据文件mkdir -p /var/sentinel/5000#寄存日志文件mkdir -p /var/log/snetinelcd /var/log/snetineltuoch /var/log/snetinel/sentinel.log2.2批改配置sentinel.conf的默认配置在reids的装置目录曾经有咱们将它copy到/etc/sentinel下,做如下批改 cp /usr/local/redis-6.0.6/sentinel/sentinel.conf /ect/sentinel/5000.confvim 5000.confprot 5000bind 本机IP或者间接正文掉dir /var/sentinel/5000sentinel monitor mymaster <masterIP> <masterPort> 2sentinel down-after-milliseconds mymaster 30000sentinel failover-timeout mymaster 60000sentinel parallel-syncs mymaster 1logfile "/var/log/snetinel/sentinel.log"daemonize yes #如果redis master配置拜访口令须要如下配置sentinel auth-pass mymaster <password>依照步骤咱们将其它两台哨兵都配置好。 3、启动哨兵在三台服务器上别离启动哨兵节点 redis-sentinel /etc/sentinal/5000.conf哨兵状态检测 redis-cli -h <节点IP> -p 5000sentinel master mymasterSENTINEL slaves mymasterSENTINEL sentinels mymasterSENTINEL get-master-addr-by-name mymaster哨兵启动实现查看日志顺利完成。 ⚠️ *这里有个问题咱们在做容灾的时候,redis集群配置了口令, 如果master节点挂了会进行故障转移从新选举master,然而当原来的master节点重启后会发现连贯不上以后master,因为在原master配置中没有加 masterauth password master节点明码的配置,给加上在重启就主动成slave节点退出到集群中。* 4、配置解释sentinel monitor master-group-name hostname port quorumsentinel down-after-milliseconds mymaster 60000sentinel failover-timeout mymaster 180000sentinel parallel-syncs mymaster 1quorum的解释如下: ...

April 16, 2021 · 1 min · jiezi

关于java:阿里P8工程师整理的22本Java架构师核心书单先收藏起来

轻易关上一个招聘网站,看看对高级Java工程师的技能要求。 抛开其它的教训能力等等,单纯从技术,或者说常识上来讲,能够发现一些共通的中央。 Java根底计算机根底数据库,SQL/NoSQL罕用开源框架分布式/微服务中间件,缓存、消息中间件书籍是获取常识的最好起源之一。技术书籍浩如烟海,市场上有不少《XXX入门到精通》,《XXX王者归来》,《21天学会XXX》这样的书,当然也有不少经典,集体的精力有限,这些经典不可能都通读。所以·,博主尝试整顿一个Java工程师所需常识的外围书单,尽可能优中选优,挑选出Java工程师必备常识的一些最外围、最经典的书籍,心愿能一起学习,一起提高。 上面举荐的这些书籍我找了很久的电子档才集齐,能够收费分享给大家一起学习,点击下方蓝字能够间接支付。 Java工程师外围书单支付Java根底「《Java核心技术》」 不必多说,Java畛域最有影响力和价值的著述之一。 「《Java编程思维》」 这个也不必多介绍了吧,永恒的经典。![](https://upload-images.jianshu.io/upload_images/26085619-ee4db0bad30047e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)下面两部经典,白璧微瑕的大略就是翻译了,技术译著难免会有些词不达意的中央,英语浏览能力过关的话能够看英文原作。国内的《疯狂Java讲义》也尚可。 Java进阶并发「《Java并发编程的艺术》」 博主感觉不错,但豆瓣评分没有设想的高,可能是三人单干,导致内容有些不连贯。国内作者写的Java并发书籍,比较简单易懂,广为流传的Java线程状态变动图就出自本书。 还有一本《Java并发编程实战》,Java并发工具包次要作者之一的著述,然而翻译的锅,能看原版的倡议看原版。 JUC相干最好的材料还是看源码,Doug Lea把他的One Peace都藏在了那里。 JVM「《深刻了解Java虚拟机》」 JVM,这一本就够了。有个博主写过:”你看到一篇JVM的文章,如果文章的最初没有写参考这本书,那肯定是作者的版权意识不够。“ 程序优化《Effective Java》 和《Java编程思维》一样被称为神书,介绍了如何写强壮,高效的代码,当然浏览须要有肯定的开发教训。 框架Spirng「《Spring实战》」 Spring入门经典书籍。 「《Spring揭秘》」 书比拟老,然而概念和原理很清晰,看完之后,再看Spring5的源码也很不错。 SpringBoot「《深入浅出Spring Boot 2.x》」 博主看过不少SpringBoot的书籍,个人感觉这本还不错,比拟具体、全面。 MyBatisMyBatis官网文档曾经做得足够好了,根本的应用查看官网就够了。 「《MyBatis技术底细》」 MyBatis源码解析的书不多,举荐这本,联合源码浏览更佳。 计算机根底数据结构与算法四大基础课中对Java工程师最重要的应该是《数据结构》,数据结构和算法个别不分家,所以放在一起。 「《数据结构与算法剖析》」 国外数据结构与算法剖析方面的经典教材,内容全面、周密严格。 其实想举荐一本教材——严蔚敏老师的《数据结构》,然而这本书是C语言版的,代码实现也不是很多,所以看起来可能比拟吃力。 还有另外一本《算法导论》,不多说了 计算机网络「《计算机网络》」 还是忍不住举荐一本教材,比拟全面、零碎,但对非科班选手可能不敌对。 「《图解HTTP》」 这本不必多介绍了吧,很活泼的解说HTTP协定的书籍,浏览起来比拟敌对。 操作系统「《深刻了解计算机系统》」 评估十分不错的计算机操作系统书籍,然而这种黑皮书可能啃起来有些艰难。 这里带过了四大根底中的《计算机组成原理》,相比拟一些比方嵌入式之类比拟底层的开发而言,计组对Java开发可能没那么重要。当然,只是相对而言,了解一些编码、运算、指令、IO之类的还是对理解底层很有帮忙的。作者学的时候用的唐朔飞编著的《计算机组成原理》教材。 数据库MySQL「《SQL必知必会》」 十分受欢迎的MySQL入门书籍,也能够当作工具书来用。 「《高性能MySQL》」 MySQL畛域的经典著作,进阶必看。 Redis「《Redis 开发与运维》」 从开发、运维两个角度总结了 Redis 实战经验,深入浅出地分析底层实现,蕴含大规模集群开发与运维的理论案例。一些api的介绍也是以Java为主。![](https://upload-images.jianshu.io/upload_images/26085619-62c409ce3c88710c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)「《Redis设计与实现》」 Redis进阶经典书籍。 对于另一个风行的NoSQL MongoDB,思考到利用场景没有下面两个宽泛,所以没有列出,博主看过的《MongoDB实战》,感觉还能够。 分布式/微服务「《SpringCloud微服务实战》」 还不错的SpringCloud书籍吧。 「《Spring Cloud Alibaba 微服务原理与实战》」 Netflex的一些组件进入了保护的状态,Spring Cloud Alibaba在最近风行了起来(技术的变迁真的太快),这方面的书不多,这本是相对而言举荐的多一些的。 常常被拿来和SpringCloud比拟的另一个开源分布式框架,官网文档大略就曾经足够了吧。 消息中间件风行的三大消息中间件,各挑出一本吧。 「《RabbitMQ实战指南》」 简略清晰的RabbitMQ技术书籍。 ...

April 16, 2021 · 1 min · jiezi

关于redis:故障分析-Redis-故障诊断及常用运维命令内存篇

作者:任仲禹 爱可生 DBA 团队成员,善于故障剖析和性能优化,文章相干技术问题,欢送大家一起探讨。 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。 本文目录: 背景 Redis 内存耗费划分内存 OOM 会导致哪些问题?排查思路 是否数据量太大?是否客户端输出缓冲区有问题?是否复制积压缓冲区有问题?是否客户端输入缓冲区有问题?实用命令 模仿 Redis 压力相干命令常⽤ Redis 内存排查命令总结 背景你是否有过这种困扰:我的数据量十分小,但还是报 OOM 谬误? # ⼀个简略set提醒内存不⾜[root@10-186-61-38 redis]# redis-cli -p 9999 set actionsky 1(error) OOM command not allowed when used memory > 'maxmemory'.首先我给大家解释下,Redis 的 OOM 分两种。 ⼀种是因 Redis 应用内存超出 OS 物理内存,OS 将 Redis 过程杀死。另⼀种是 Redis 应用内存超过 maxmemory 参数配置,引发 Redis Server 层 OOM。OOM 是 Redis 最常见的内存故障,它影响很大: 故障产生时,过程并不会退出,能读但无奈写入。配置了 allkeys-lru、allkeys-lfu 等内存淘汰策略场景下,会有大量键生效,导致缓存命中率急剧下降。本文中,我会给大家分享下该种内存问题的排查方向及运维命令。 Redis 内存耗费划分 简短介绍下 Redis 内存耗费划分状况,为下文诊断提供思路。上图能够总结 Redis 耗费内存分如下几块: ...

April 16, 2021 · 2 min · jiezi

关于redis:分布式锁注意点及其实现

分布式锁留神点1)互斥性在任意时刻只有一个客户端能够获取锁 2)防死锁如果一个客户端在持有锁的时候解体了,没有开释锁,那么别的客户端无奈取得锁,则会造成死锁,所以要保障客户端肯定会开释锁。Redis中咱们能够设置锁的过期工夫来保障不会产生死锁。 3)持锁人解锁解铃还须系铃人,加锁和解锁必须是同一个客户端,客户端A的线程加的锁必须是客户端A的线程来解锁,客户端不能解开别的客户端的锁。 4)可重入当一个客户端获取对象锁之后,这个客户端能够再次获取这个对象上的锁。 redis分布式锁实现Redis 锁次要利用 Redis 的 setnx 命令。 加锁命令:SETNX key value,当键不存在时,对键进行设置操作并返回胜利,否则返回失败。KEY 是锁的惟一标识,个别按业务来决定命名。解锁命令:DEL key,通过删除键值对开释锁,以便其余线程能够通过 SETNX 命令来获取锁。锁超时:EXPIRE key timeout, 设置 key 的超时工夫,以保障即便锁没有被显式开释,锁也能够在肯定工夫后主动开释,防止资源被永远锁住。则加锁解锁伪代码如下: if (setnx(key, 1) == 1){ expire(key, 30) try { //TODO 业务逻辑 } finally { del(key) }}留神点SETNX 和 EXPIRE 非原子性如果 SETNX 胜利,在设置锁超时工夫后,服务器挂掉、重启或网络问题等,导致 EXPIRE 命令没有执行,锁没有设置超时工夫变成死锁。 解决办法 setnx的时候,value设置和过期工夫设置不是原子,能够用set命令,redis版本2.6.12当前lua脚本,示例如下if (redis.call('setnx', KEYS[1], ARGV[1]) < 1)then return 0;end;redis.call('expire', KEYS[1], tonumber(ARGV[2]));return 1;// 应用实例EVAL "if (redis.call('setnx',KEYS[1],ARGV[1]) < 1) then return 0; end; redis.call('expire',KEYS[1],tonumber(ARGV[2])); return 1;" 1 key value 100谬误解除如果线程 A 胜利获取到了锁,并且设置了过期工夫 30 秒,但线程 A 执行工夫超过了 30 秒,锁过期主动开释,此时线程 B 获取到了锁;随后 A 执行实现,线程 A 应用 DEL 命令来开释锁,但此时线程 B 加的锁还没有执行实现,线程 A 理论开释的线程 B 加的锁。 ...

April 16, 2021 · 1 min · jiezi

关于redis:建议收藏看完全面掌握最详细的Redis总结2021最新版

Redis简介Redis 是一个应用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。 Redis 能够存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值反对五种数据类型:字符串、列表、汇合、散列表、有序汇合。 与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度十分快,因而 redis 被广泛应用于缓存方向,每秒能够解决超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也常常用来做分布式锁。除此之外,Redis 反对事务 、长久化、LUA脚本、LRU驱动事件、多种集群计划(Redis 6.0 集群搭建实际)。 从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal资助。 Redis的优缺点长处读写性能优异, Redis能读的速度是110000次/s,写的速度是81000次/s。反对数据长久化,反对AOF和RDB两种长久化形式。反对事务,Redis的所有操作都是原子性的,同时Redis还反对对几个操作合并后的原子性执行。数据结构丰盛,除了反对string类型的value外还反对hash、set、zset、list等数据结构。反对主从复制,主机会主动将数据同步到从机,能够进行读写拆散。毛病数据库容量受到物理内存的限度,不能用作海量数据的高性能读写,因而Redis适宜的场景次要局限在较小数据量的高性能操作和运算上。Redis 不具备主动容错和复原性能,主机从机的宕机都会导致前端局部读写申请失败,须要期待机器重启或者手动切换前端的IP能力复原。主机宕机,宕机前有局部数据未能及时同步到从机,切换IP后还会引入数据不统一的问题,升高了零碎的可用性。Redis 较难反对在线扩容,在集群容量达到下限时在线扩容会变得很简单。为防止这一问题,运维人员在零碎上线时必须确保有足够的空间,这对资源造成了很大的节约。数据类型Redis次要有5种数据类型,包含String,List,Set,Zset,Hash,满足大部分的应用要求。具体的可参考:Redis 的 8 大数据类型,写得十分好! 应用场景因为Redis优异的读写性能,长久化反对等劣势,Redis的应用场景十分多,次要包含计数器,缓存,音讯队列,分布式锁等,具体应用场景如下: 计数器 能够对 String 进行自增自减运算,从而实现计数器性能。Redis 这种内存型数据库的读写性能十分高,很适宜存储频繁读写的计数量。缓存 将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保障缓存的命中率。会话缓存 能够应用 Redis 来对立存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具备状态,一个用户能够申请任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。全页缓存(FPC) 除根本的会话token之外,Redis还提供很简便的FPC平台。以Magento为例,Magento提供一个插件来应用Redis作为全页缓存后端。此外,对WordPress的用户来说,Pantheon有一个十分好的插件 wp-redis,这个插件能帮忙你以最快速度加载你曾浏览过的页面。查找表 例如 DNS 记录就很适宜应用 Redis 进行存储。查找表和缓存相似,也是利用了 Redis 疾速的查找个性。然而查找表的内容不能生效,而缓存的内容能够生效,因为缓存不作为牢靠的数据起源。音讯队列(公布/订阅性能) List 是一个双向链表,能够通过 lpush 和 rpop 写入和读取音讯不过最好应用 Kafka、RabbitMQ 等消息中间件。分布式锁实现 在分布式场景下,无奈应用单机环境下的锁来对多个节点上的过程进行同步。能够应用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还能够应用官网提供的 RedLock 分布式锁实现。其它 Set 能够实现交加、并集等操作,从而实现独特好友等性能。ZSet 能够实现有序性操作,从而实现排行榜等性能。长久化Redis 是内存型数据库,为了之后重用数据(比方重启机器、机器故障之后回复数据),或者是为了避免系统故障而将数据备份到一个近程地位,须要将内存中的数据长久化到硬盘上。 Redis 提供了RDB和AOF两种长久化形式。默认是只开启RDB,当Redis重启时,它会优先应用AOF文件来还原数据集。 Redis长久化详解能够参考:Redis长久化 过期键的删除策略Redis中有个设置工夫过期的性能,即对存储在 redis 数据库中的值能够设置一个过期工夫。作为一个缓存数据库,这是十分实用的。如咱们个别我的项目中的 token 或者一些登录信息,尤其是短信验证码都是有工夫限度的,依照传统的数据库解决形式,个别都是本人判断过期,这样无疑会重大影响我的项目性能。 ...

April 15, 2021 · 3 min · jiezi

关于golang:REDIS-安装与使用

[TOC] REDIS 装置与应用Centos 零碎 redis装置1 下载安装包https://redis.io/download 2 解压并装置前置条件装置gcc ,g++ ,make sudo apt-get install build-essential下载cmake压缩包 tar -zxvf cmake-3.13.4-Linux-x86_64.tar.gz -C /opt/配置/etc/profile export PATH=$PATH:/opt/cmake-3.13.4-Linux-x86_64/bin若上述环境装置过,则间接进行下一步 tar xvf redis-6.2.1.tar.gz 进入 redis目录后 编译 make cd redis-6.2.1make装置 redis 到 /usr/local make PREFIX=/usr/local/redis install拷贝配置文件到 /usr/local/redis/ 下 cp redis.conf /usr/local/redis/3 批改配置文件进入redis目录 cd /usr/local/redis/批改配置文件 vim /usr/local/redis/redis.conf找到 daemonize , 将其批改为 yesdaemonize yes找到bind ,将其批改为0.0.0.0bind 0.0.0.0找到protected-mode 批改为 noprotected-mode no找到 requirepass 批改明码为本人须要的明码 如123456requirepass 1234564 redis的基本操作启动redis服务端/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf查看过程ps aux |grep redis查看端口netstat -antp 6379redis客户端连贯服务端/usr/local/redis/bin/redis-cli -h xxxx -p 6379 -a 本人的明码# 敞开redis/usr/local/redis/bin/redis-cli shutdownubuntu 零碎 redis装置前置条件,更新本人的库sudo apt update sudo apt full-upgradesudo apt install build-essential tcl装置redis-server装置后的目录是在 /etc/redis/ 上面 ...

April 15, 2021 · 1 min · jiezi

关于redis:Django-Http-Docker-面试问题整理

1,Django的生命周期 a. wsgi, 创立socket服务端,用于接管用户申请并对申请进行首次封装。b. 中间件,对所有申请到来之前,响应之前定制一些操作。c. 路由匹配,在url和视图函数对应关系中,依据以后申请url找到相应的函数。d. 执行视图函数,业务解决【通过ORM去数据库中获取数据,再去拿到模板,而后将数据和模板进行渲染】e. 再通过所有中间件。f. 通过wsgi将响应返回给用户。2,TCP/IP由四个档次组成:数据链路层、网络层、传输层、应用层。 数据链路层这是TCP/IP软件的最低层,负责接管IP数据报并通过网络发送,或者从网络上接管物理帧,抽出IP数据报,交给IP层。网络层负责相邻计算机之间的通信。其性能包含三方面:a、解决来自传输层的分组发送申请,收到申请后,将分组装入IP数据报,填充报头,抉择去往信宿机的门路,而后将数据报发往适当的网络接口。b、解决输出数据报:首先查看其合法性,而后进行寻径–如果该数据报已达到信宿机,则去掉报头,将剩下局部交给适当的传输协定;如果该数据报尚未达到信宿,则转发该数据报。c、解决门路、流控、拥塞等问题。传输层提供应用程序间的通信。其性能包含:a、格式化信息流;b、提供牢靠传输。为实现后者,传输层协定规定接收端必须发回确认,并且如果分组失落,必须从新发送。应用层向用户提供一组罕用的应用程序,比方电子邮件、文件传输拜访、近程登录等。近程登录TELNET应用TELNET协定提供在网络其它主机上注册的接口。TELNET会话提供了基于字符的虚构终端。文件传输拜访FTP应用FTP协定来提供网络内机器间的文件拷贝性能。3,应用orm和原生sql的优缺点,解决并发问题? 1.orm的开发速度快,操作简略。使开发更加对象化 #执行速度慢。解决多表联查等简单操作时,ORM的语法会变得复杂2.sql开发速度慢,执行速度快。性能强4,Web开发中有哪些技术手段避免SQL注入? 1.应用预编译绑定变量的SQL语句2.严格加密解决用户的机密信息3.不要随便开启生产环境中Webserver的谬误显示4.应用正则表达式过滤传入的参数5.字符串过滤6.查看是否包函非法字符5,谈谈CSRF原理 你这能够这么了解CSRF攻打:攻击者盗用了你的身份,以你的名义发送歹意申请。CSRF可能做的事件包含:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚构货币转账......造成的问题包括:个人隐私泄露以及财产平安。要实现一次CSRF攻打,受害者必须顺次实现两个步骤:1.登录受信赖网站A,并在本地生成Cookie。2.在不登出A的状况下,拜访危险网站B。6,如果用户投诉说网页加载很慢,并且不是网速问题,大略10秒钟左右能力显示进去。当初让你来定位这个问题,请用一个最间接的办法,疾速的定位到问题呈现的地位,不保障百分之百能定位到,然而你这个办法必须百分之80或者90能定位呈现问题的地位。 7,docker和虚拟机 传统虚拟机技术是虚构出一套硬件后,在其上运行一个残缺操作系统,在该零碎上再运行所需利用过程。操作系统其磁盘占用至多几十G起步,内存要几个G起步。启动时要从头到尾把该检测的都检测了该加载的都加载上,这个过程十分迟缓。 而容器内的利用过程间接运行于宿主的内核,容器内没有本人的内核,而且也没有进行硬件虚构,因而容器要比传统虚拟机更为轻便。每个容器有本人的文件系统 ,容器之间过程不会相互影响,能辨别计算资源。8,docker容器之间怎么隔离 Linux中的PID、IPC、网络等资源是全局的,而NameSpace机制是一种资源隔离计划,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace,各个NameSpace下的资源互不烦扰。尽管有了NameSpace技术能够实现资源隔离,但过程还是能够不受控的拜访系统资源,比方CPU、内存、磁盘、网络等,为了管制容器中过程对资源的拜访,Docker采纳control groups技术(也就是cgroup),有了cgroup就能够管制容器中过程对系统资源的耗费了,比方你能够限度某个容器应用内存的下限、能够在哪些CPU上运行等等。有了这两项技术,容器看起来就真的像是独立的操作系统了。9,Celery的架构和运行过程 消息中间件(message broker),工作执行单元(worker)和工作执行后果存储(task result store)组成。1、客户端也就是python(django/flask等)公布工作2、公布的工作存到工作队列外面,能够以redis、rabbitMQ、MessageQueue、MySQL存储,个别在django/flask程序里redis居多3、工作解决者会一直从工作队列外面获取工作执行10,redis根本数据类型 String字符串:Hash(哈希)List(列表)Set(汇合)zset(sorted set:有序汇合)11,django罕用中间件 缓存中间件通用中间件内容压缩中间件(GZip)本地化中间件(Locale)消息中间件(Message)于cookie或者会话的音讯性能,比拟罕用。平安中间件SecurityCSRF protection认证框架 Authentication12,django uuid字段自增

April 15, 2021 · 1 min · jiezi

关于java:浅谈redis的set-get布隆过滤器

布隆过滤器是什么 在做JAVA我的项目时候用到这个(参考地址),明天咱们就讲一讲 名字就跟每个定律一样,你问为什么叫牛顿定律,因为是牛顿创造或者发现的。 他能做什么?它是将一个二进制向量和函数映射,布隆过滤器能够用在检测元素是否存在某个汇合或者用于疾速检索中。 毛病: 有肯定的删除问题和谬误识别率 长处:查问工夫和空间都远远超过一般算法 布隆过滤器Bloom Filter 是怎么实现的 增加Item或者元素时,创立一个散列函数和一个KEY造成映射,设置的数据=1,只有检索时判断 =1就晓得这个数据存不存在,有了此办法,查问时发现有0的则证实肯定不存在,那么反过来讲如果是1证实元素很可能存在, 留神这里为什么说很可能存在,因为他有肯定的辨认谬误,但这个谬误在理论生产过程中能够疏忽,毕竟利大于弊么。 看文字晕晕乎乎,不动就画图,来看看应该就会明确许多。 说人话 布隆过滤器到底无能啥? 非凡的id暂且不提哈,数据库id根本都是自增的对吧!咱们传递id后端去DB查问,这个十分正当。 然而如果咱们用正数查问呢?一两条无所谓,如果成千上万呢?基本上数据库都会很大压力扛不住,服务器配置暂且不说,拖慢零碎运行速度甚至宕机都是有可能的,这样是不是布隆过滤器的有点有展示的酣畅淋漓。【狗头】 这么吊,也是有代价的,因为它也拿不准,存在肯定水平的判断失误! 问:为什么会误判? 答:搜寻的key没在容器中,然而hash后失去的key都是1 。如果布隆过滤器中有黑名单,那么间接创立一个白名单就搞定了。 问:为什么不容易删除? 答:咱们提到正确的数据Key值=1,但不能因为=0就删掉他,这可能会影响其余元素的判断 不过能够理解下Counting Bloom Filter 「下一篇文章」 说了这么多咋实现 1:预估数量n以及冀望的误判率FPP 2: hash函数和bit汇合的size大小 Bit汇合Size大小 函数 哈希抉择,预估值n和bit数组长度m获取hash函数Key 怎么用?maven我的项目中增加 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency> 一段我写的测试代码 /** * 布隆过滤器 - 用于redis缓存穿透 的状况public class TestBloomFilterByDZZ { private static int total = 19999; private static BloomFilter<Integer> bfilter = BloomFilter.create(Funnels.integerFunnel(), total); // 初始化数据 public static void main(String[] args) { for (int i = 0; i < total; i++) { bfilter.put(i); } // 是否有匹配不上的 for (int i = 0; i < total; i++) { if (!bfilter.mightContain(i)) { System.out.println("有没关注东南大粽子的 溜了。。。"); } } // 不再内的有多少匹配进去 int count = 0; for (int i = total; i < total + 10000; i++) { if (bfilter.mightContain(i)) { count++; } } System.out.println("炮灰陪跑:" + count); }}可实用的业务场景 ...

April 14, 2021 · 1 min · jiezi

关于redis:面试时别只说会redis-get-set-布隆过滤器了解下

布隆过滤器是什么名字就跟每个定律一样,你问为什么叫牛顿定律,因为是牛顿创造或者发现的。「瞪眼」 他能做什么?它是将一个二进制向量和函数映射,布隆过滤器能够用在检测元素是否存在某个汇合或者用于疾速检索中。 毛病: 有肯定的删除问题和谬误识别率 长处:查问工夫和空间都远远超过一般算法 布隆过滤器Bloom Filter 是怎么实现的增加Item或者元素时,创立一个散列函数和一个KEY造成映射,设置的数据=1,只有检索时判断 =1就晓得这个数据存不存在,有了此办法,查问时发现有0的则证实肯定不存在,那么反过来讲如果是1证实元素很可能存在, 留神这里为什么说很可能存在,因为他有肯定的辨认谬误,但这个谬误在理论生产过程中能够疏忽,毕竟利大于弊么。 看文字晕晕乎乎,不动就画图,来看看应该就会明确许多。 说人话布隆过滤器到底无能啥? 非凡的id暂且不提哈,数据库id根本都是自增的对吧!咱们传递id后端去DB查问,这个十分正当。 然而如果咱们用正数查问呢?一两条无所谓,如果成千上万呢?基本上数据库都会很大压力扛不住,服务器配置暂且不说,拖慢零碎运行速度甚至宕机都是有可能的,这样是不是布隆过滤器的有点有展示的酣畅淋漓。【狗头】 这么吊,也是有代价的,因为它也拿不准,存在肯定水平的判断失误! 问:为什么会误判? 答:搜寻的key没在容器中,然而hash后失去的key都是1 。如果布隆过滤器中有黑名单,那么间接创立一个白名单就搞定了。 问:为什么不容易删除? 答:咱们提到正确的数据Key值=1,但不能因为=0就删掉他,这可能会影响其余元素的判断 不过能够理解下Counting Bloom Filter 「下一篇文章」 说了这么多咋实现1:预估数量n以及冀望的误判率FPP 2: hash函数和bit汇合的size大小 Bit汇合Size大小 函数 哈希抉择,预估值n和bit数组长度m获取hash函数Key 怎么用?maven我的项目中增加 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency> 一段我写的测试代码 /** * 布隆过滤器 - 用于redis缓存穿透 的状况 * @author 作者 东南大粽子 */public class TestBloomFilterByDZZ { private static int total = 19999; private static BloomFilter<Integer> bfilter = BloomFilter.create(Funnels.integerFunnel(), total); // 初始化数据 public static void main(String[] args) { for (int i = 0; i < total; i++) { bfilter.put(i); } // 是否有匹配不上的 for (int i = 0; i < total; i++) { if (!bfilter.mightContain(i)) { System.out.println("有没关注东南大粽子的 溜了。。。"); } } // 不再内的有多少匹配进去 int count = 0; for (int i = total; i < total + 10000; i++) { if (bfilter.mightContain(i)) { count++; } } System.out.println("炮灰陪跑:" + count); }}可实用的业务场景1:当一个入库数据量比拟大的时候,能够用作名称或者惟一件做查看,存在则跳过不存在则入库 ...

April 14, 2021 · 1 min · jiezi

关于华为云:华为云PB级数据库GaussDBfor-Redis揭秘第七期高斯Redis与强一致

摘要:在KV数据库畛域,“强一致性”不仅是一个技术名词,它更是业务与运维的重要需要。本文分享自华为云社区《华为云PB级数据库GaussDB(for Redis)揭秘第七期:高斯Redis与强统一》,原文作者:高斯Redis官网博客。 清明刚过,五一假期就要来了。大好春光,不如去婺源看油菜花吧!小云迅速关上APP刷出余票2张,连忙下单!唉,怎么又没抢到!转念一想倒也能了解:从勾选乘车人到正式下单,起码要10秒,真若是“见者有份”,恐怕这两个座位大家要挤挤共用了!每逢节假日,全国几百万小伙伴同时查票订票,12306是如何保障余票显示准、车票不超卖的? 于是,按捺不住好奇心,笔者进行了一番深入研究。原来,问题背地暗藏着一个分布式数据库畛域极其要害的技术——数据强一致性保障。 1. 什么是强统一?在介绍概念之前,咱们无妨先来模仿一场球赛直播。 假如笔者做了一款APP,后盾应用上图的主从数据库。比分写入主节点,从节点分担用户查问。较量中,Alice惊呼较量完结,Bob闻声刷新APP,却显示较量仍在持续!Bob体验到了显著的数据不统一,于是默默给APP打了个差评…… 那么,产生不统一的起因到底是什么? 异步复制时,主节点不期待从节点写入就间接返回了。因为网络提早等起因,从节点无奈保障更新工夫。Alice和Bob明明在同时同地查问同一零碎,失去正确后果却有先有后。其实这就是典型的弱一致性。 实际上,为解决单点故障、加强吞吐性能,分布式数据库外部都会对同一份数据进行复制,把冗余正本扩散保留到不同节点上。简略的异步复制只能构建出弱统一零碎,很难满足业务要求。 那么,到底什么样的一致性才靠谱?有哪些类别?上面咱们就来意识这个神秘家族! 1.1 强一致性/线性一致性(Linearizability) 一致性的最高规范,实现难度最高。外围要求是:一旦写操作实现,随后任意客户端的查问都必须返回这一新值。以下图为例,一旦“写入b”实现,必须保障读到b。而写入过程中,认为值的跳变可能产生在某一瞬间,因而读到a或b都是可能的。 从业务角度来说,强一致性带来的体验几乎能够用丝滑来形容!因为它外部的数据“好像”只有一份,即便并发拜访不同节点,每个操作也都能原子有序。正因如此,强统一数据库在业务架构中往往被用在要害地位。 etcd是强统一俱乐部里的元老。它基于Raft共识算法,真正实现了强统一,也因而在Leader选举、服务发现等场景起到重要作用。GaussDB(for Redis)作为一款分布式云数据库,凭借多年潜心打磨,也是强统一的代言人。 1.2 程序一致性(Sequential Consistency) 弱于线性统一,不保障操作的全局时序,但保障每个客户端操作能按程序被执行。下图中,A先写x=10,后写x=20;B先写x=99,后写x=999。当C读取时,程序一致性保障了10先于20被读到、99先于999被读到。 Zookeeper基于ZAB协定,所有写操作都经由主节点协调,实现了程序一致性。 1.3 因果一致性(Causal Consistency) 进一步放宽要求,只对并发拜访中具备因果关系的操作保序。例如: A写入3,B读到后乘以100再更新它。在这个场景下,因为“A写入3”与“B写入300”有着明确因果关系,因果一致性保障300晚于3被读到。 因果一致性多用于各种博客的评论零碎、社交软件等。天然,咱们回复某条评论的内容,不应早于评论自身被显示进去。 1.4 最终一致性(Eventual Consistency)进行写入并期待一段时间,最终所有客户端都能读到雷同的新数据,但具体时限不作保障。许多分布式数据库满足最终一致性,如MySQL主从集群等。 然而,这其实是一个十分弱的保障。因为不确定零碎外部过多久能力收敛统一,在此之前,用户随时可能体验到数据不统一。因而最终一致性有人造的局限性,常常会给业务逻辑带来凌乱。 1.5 弱一致性(Weak Consistency) 说它最为“厚脸皮”也不为过,因为它连数据写入后未来被读到都不能保障!弱一致性实现技术门槛低,利用场景也不多。严格来说,单纯的开源Redis主从集群就属于这一类别。 OK,一致性家族的各位成员曾经跟大家打过照面。显然,一致性越强的数据库系统,可能撑持的业务场景越多。有的业务同学小声说,强统一技术再牛,可我业务简略,不必也没关系吧。实际上恰恰相反: 强统一不仅仅是技术问题,它更是一个不可漠视的业务需要、运维需要! 接下来咱们就先来聊一聊:业务上那些只有强统一能力搞定的事儿! 2 强统一是业务刚需2.1 计数器/限流器计数服务是典型的强统一利用场景。电商在秒杀流动中,往往会搭建Redis主从集群给上层MySQL做缓存。因为要抗住超大流量,须要Redis的计数器性能做限流。简略讲,咱们初始化counter=5000。随后每次业务拜访都执行DECR命令,当counter归零就阻塞后续申请。此外,每隔一个时间段重置counter=5000,通过这样的伎俩来实现“细水长流”。 然而,完满的假如还不够! 开源Redis采纳异步复制,如遇网络不畅,常常产生主节点复制buffer沉积。这将导致从节点counter偏大很多。此时,一旦主节点宕机,切换到从节点继续执行DECR命令,压力很容易超出阈值,全副落到上层软弱的MySQL,随时可能引起零碎雪崩! 因而,在限流场景下,只有真正的强统一能力提供牢靠的计数器。 2.2 Leader选举当业务部署的节点较多、可用性要求高时,往往要用到Leader选举。etcd作为强统一KV存储,能完满cover这一场景。etcd依赖两大性能实现Leader选举: 1)TTL:给key设置有效期,到期后key主动删除。 2)CAS:对key的原子操作。(这一性能只有强统一数据库能力实现) 应用etcd搭建Leader选举服务的设计如下: 1)约定key,用于选举时抢占。其value用于保留Leader节点名称。 2)约定TTL,用于给key设定有效期。 3)启动时:每个参加节点尝试cas create key&设置TTL。在etcd集群强统一CAS机制保障下,只有一个节点能执行胜利。该节点成为Leader并将名称写入value;其余节点成为Follower。 4)运行中:每个节点定期TTL/2尝试get key,将value与本身名称比照: 如雷同,阐明已是Leader,尔后只需每隔TTL/2刷新key的TTL即可。如不同,阐明是Follower,接下来要每隔TTL/2执行cas create key&设置TTL。5)当Leader节点异样退出,无奈刷新TTL,key会很快过期。此时,其余Follow之中便会有新的Leader产生。 从原理上能看出,强统一能力是Leader选举的根基。相似的“刚需”业务场景还有很多,强统一不可或缺。 好了,业务上的事儿就聊到这里,接下来让咱们听听运维怎么说。 3. 强统一为运维减负3.1 辅助组件架构简单、问题难定位后盾架构中,MySQL主从热备也是常见的部署形式。因为数据保留在本地磁盘中,当主库产生重大故障,仅仅依附MySQL本身同步机制,主从切换后无奈保障所提供数据与之前状态完全一致。于是呈现了“重量级”的辅助组件——MHA(Master High Availability)。咱们来看一下它的部署形式: MHA负责在故障转移过程中,帮忙从库尽量追平主库最新状态,提供近似统一的数据。但这一能力须要额定的Manager节点,同时还要在每一个MySQL节点上部署Node服务。故障切换时,Manager先为从库补充落后的数据,再通过切换VIP复原用户拜访,过程可能长达数十秒。 ...

April 14, 2021 · 1 min · jiezi

关于redis:Redis布隆过滤器分析与总结

问题引入问题一:本来有10亿个号码,当初又来了10万个号码,要疾速精确判断这10万个号码是否在10亿个号码库中? 问题二:接触过爬虫的,应该有这么一个需要,须要爬虫的网站千千万万,对于一个新的网站url,咱们如何判断这个url咱们是否曾经爬过了? 问题三:一个邮件系统,有上亿的邮件数量,咱们要检测某一个邮箱是否正确发送了邮件信息? 问题四:提到Redis做缓存查问,咱们须要思考几个问题,缓存穿透、缓存击穿和缓存雪崩。咱们该如何解决缓存这种缓存问题呢? 布隆过滤布隆过滤器其实就是,一种数据结构,是由一串很长的二进制向量组成,能够将其看成一个二进制数组。既然是二进制,那么外面寄存的不是0,就是1,然而初始默认值都是0。 大抵的数据结构如下图: 增加数据: 向布隆过滤器中增加 key 时,会应用多个 hash 函数对 key 进行 hash 算得一个整数索引值而后对位数组长度进行取模运算失去一个地位,每个 hash 函数都会算得一个不同的地位。再把位数组的这几个地位都置为 1 就实现了 add 操作。 获取数据时: 只须要将这个新的数据通过下面自定义的几个哈希函数,别离算出各个值,而后看其对应的中央是否都是1,如果存在一个不是1的状况,那么咱们能够说,该新数据肯定不存在于这个布隆过滤器中。 Redis配置在Redis中要应用布隆过滤器,能够间接参照该文档,文档地址 举荐应用docker应用形式,如果要编译成so动静库,则须要运行在Linux环境中。// 装置docker run -p 6377:6379 --name redis-redisbloom redislabs/rebloom:latest装置完之后,查看docker容器。进入Redis容器,并查看容器模块状态。 # 进入容器docker exec -it 4a695ead6577 /bin/sh# 登录到Redisredis-cli# 查看Redis模块127.0.0.1:6379> info Modules# Modulesmodule:name=bf,ver=20205,api=1,filters=0,usedby=[],using=[],options=[]操作演示增加数据 // 单个增加127.0.0.1:6379> bf.add blkey 1(integer) 1127.0.0.1:6379> bf.add blkey 2(integer) 1127.0.0.1:6379> bf.add blkey 2(integer) 0127.0.0.1:6379> bf.add blkey 3(integer) 1127.0.0.1:6379> bf.add blkey 4(integer) 1// 批量增加127.0.0.1:6379> bf.madd blkey 5 6 7 8 41) (integer) 12) (integer) 13) (integer) 14) (integer) 15) (integer) 0通过增加会发现,如果元素曾经存在,则返回的是0值。检测数据 ...

April 13, 2021 · 3 min · jiezi

关于redis集群:使用Docker进行Redis主从复制实践

一、背景最近在做零信赖平安网关,须要应用Redis作为认证缓存服务器,因为网关服务器散布在多个集群,每次都跨机房认证不太实现;所以须要应用Redis主从同步,将过程记录下来,心愿能够给须要的同学一点参考。 二、操作步骤装置Docker主服务配置从服务配置验证同步成果三、装置Docker本篇文章次要是问了记录主从配置的过程,因而我采纳最简略的docker形式来搭建Redis服务,装置docker的命令如下所示 curl -sSL https://get.daocloud.io/docker | sh命令执行实现之后,能够看到如下图所示界面 在上图中能够看到docker的一些相干信息,咱们要确认docker装置是否胜利还能够应用docker info命令进行查看,执行命令如下所示 docker info 命令执行之后,返回信息如下图所示在上图中能够看到docker的版本信息为20.10.3,这是目前的最新版本,曾经确认装置胜利无误。 四、主服务配置接下来我须要应用docker装置Redis服务,我在实际过程中发现间接应用Redis镜像有些异样,于是应用centos镜像,再在容器里装置Redis,运行容器的命令如下所示 docker run -d -it -p 16379:6379 --name redis_master centos:7命令执行结束之后再进入该容器,进入容器的命令如下所示 docker exec -it redis_master bash命令执行结束后,返回的信息如下图所示在上图中能够看到曾经胜利的进入到了容器外面,接下来我须要在容器里装置Redis,装置Redis的命令如下所示 yum install -y epel-release && yum install -y redis命令执行结束之后,返回的信息如下图所示 从上图中能够看到,Redis曾经装置实现,接下来须要新建一个Redis的主库配置文件,执行命令如下所示 vi ~/master.conf配置文件如下所示,将下列配置文件复制并粘贴到vi编辑窗口当中。 #bind 0.0.0.0protected-mode yesport 6379tcp-backlog 511unixsocket /tmp/redis_auth.sockunixsocketperm 777timeout 0tcp-keepalive 300daemonize yessupervised autopidfile /var/run/redis_auth.pidloglevel debuglogfile /tmp/redis_auth.logdatabases 16save ""stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump.rdbdir /var/lib/redisrequirepass 123123123slave-serve-stale-data yesslave-read-only yesrepl-diskless-sync norepl-diskless-sync-delay 5repl-disable-tcp-nodelay noslave-priority 100appendonly yesappendfilename "funfe.aof"appendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 512mbaof-load-truncated yeslua-time-limit 5000slowlog-log-slower-than 10000slowlog-max-len 128latency-monitor-threshold 0notify-keyspace-events ""hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-size -2list-compress-depth 0set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000activerehashing yeshz 10aof-rewrite-incremental-fsync yes在vi编辑窗口粘贴后,如下图所示 ...

April 11, 2021 · 1 min · jiezi

关于java:阿里P8架构师分享私用Java学习资料含视频和项目源码

前言内容涵盖:Java、MyBatis、ZooKeeper、Elasticsearch、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、 Linux 等技术栈 所有材料都是收费分享,点击Java高级架构师即可支付一、《Java工程师成神之路(根底篇)》 二、珍藏版Mybatis:入门+配置信息+印射+缓存+整合Spring+面试 三、从Paxos到Zookeeper  分布式一致性原理与实际 倪超著2015.02 四、深刻了解ElasticSearch 五、Redis小白入门指南+Redis实战 六、MySQL学习笔记 七、 深刻RabbitMQ+RabbitMQ实战  高效部署分布式音讯队列 八、(中文版)Kafka    权威指南 九、[鸟哥的Linux私房菜:服务器架设篇(第二版)].鸟哥.扫描版+循序渐进Linux第2版 +LINUX SHELL脚本攻略(中文版带书签)+《Linux命令行大全》.((美) 十、JavaEE互联网轻量级框架整合开发 SSM框架(Spring MVC+Spring+MyBatis)和Redis实现 十一、1000+道互联网大厂Java工程师面试题 每个技术栈都有相应的视频解说以及配套的我的项目实战源码分享,多达3501G的视频文档学习材料,等你来学! 好了,文章就到这里了,点击Java高级架构师支付材料,成为技术大牛,走上人生巅峰。

April 11, 2021 · 1 min · jiezi

关于java:Redis高级RDB持久化

1. 根底RDB长久化既能够手动执行,也能够依据服务器配置选项定期执行.该性能能够将某个工夫点上的数据库状态保留到一个RDB文件中。RDB长久化性能所生成的RDB文件是一个通过压缩的二进制文件,通过该文件能够还原生成RDB文件时的数据库状态 因为RDB文件是保留在硬盘外面的,所以即便Redis服务器过程退出,甚至运行Redis服务器的计算机停机,但只有RDB文件依然存在,Redis服务器就能够用它来还原数据库状态 2. SAVE命令和BGSAVE命令有两个Redis命令能够用于生成RDB文件,一个是SAVE,另一个是BGSAVE。SAVE命令会阻塞Redis服务器过程,直到RDB文件创建结束为止,在服务器过程阻塞期间,服务器不能解决任何命令申请: 和SAVE命令间接阻塞服务器过程的做法不同,BGSAVE命令会派生出一个子过程,而后由子过程负责创立RDB文件,服务器过程(父过程)持续解决命令申请:和应用SAVE命令或者BGSAVE命令创立RDB文件不同,RDB文件的载入工作是在服务器启动时主动执行的,所以 Redis并没有专门用于载入RDB文件的命令,只有Redis服务器在启动时检测到RDB文件存在,它就会主动载入RDB文件。 以下是我执行save命令后重新启动redis服务控制台打印的信息,能够看到在服务启动的时候回主动加载RDB文件 【注意事项】因为AOF 文件的更新频率通常比RDB文件的更新频率高,所以:如果服务器开启了AOF长久化性能,那么服务器会优先应用AOF 文件来还原数据库状态。只有在AOF长久化性能处于敞开状态时,服务器才会应用RDB文件来还原数据库状态。当SAVE命令执行时,Redis服务器会被阻塞,所以当SAVE命令正在执行时,客户端发送的所有命令申请都会被回绝。只有在服务器执行完SAVE命令、从新开始接受命令申请之后,客户端发送的命令才会被解决。因为BGSAVE命令的保留工作是由子过程执行的,所以在子过程创立RDB文件的过程中,Redis服务器依然能够持续解决客户端的命令申请,然而,在BGSAVE命令执行期间,服务器解决SAVE、BGSAVE、BGREWRITEAOF三个命令的形式会和平时有所不同。【留神】1、bgsave命令执行时,客户端的save命令会被服务器回绝2、在bgsave命令执行时,客户端的bgsave也会被回绝3、bgrewriteaof和bgsave命令不能同时执行 3. 主动间隔性保留因为BGSAVE命令能够在不阻塞服务器过程的状况下执行,所以Redis容许用户通过设置服务器配置的save选项,让服务器每隔一段时间主动执行一次BGSAVE命令。用户能够通过save选项设置多个保留条件,但只有其中任意一个条件被满足,服务器就会执行BGSAVE命令。上面是redis的配置文件 下面的默认配置形容如下:只有满足以下三个条件中的任意一个,BGSAVE命令就会被执行:1:服务器在900秒之内,对数据库进行了至多1次批改2:服务器在300秒之内,对数据库进行了至多10次批改3:服务器在60秒之内,对数据库进行了至多10000次批改 如果咱们想要有其余设置,能够自定义批改其配置规定 4. 主动保留条件Redis 的服务器周期性操作函数serverCron默认每隔100毫秒就会执行一次,该函数用于对正在运行的服务器进行保护,它的其中一项工作就是查看save选项所设置的保留条件是否曾经满足,如果满足的话,就执行BGSAVE命令。 5. RDB文件构造 (1)REDISRDB文件的最结尾是REDIS局部,这个局部的长度为5字节,保留着"REDIS"五个字符。通过这五个字符,程序能够在载人文件时,疾速查看所载入的文件是否RDB文件。 (2)db\_versiondb version长度为4字节,它的值是一个字符串示意的整数,这个整数记录了RDB文件的版本号,比方"0006”就代表RDB文件的版本为第六版。 (3)databasesdatabases局部蕴含着零个或任意多个数据库,以及各个数据库中的键值对数据: (4)EOFEOF常量的长度为1字节,这个常量标记着RDB文件注释内容的完结,当读入程序遇到这个值的时候,它晓得所有数据库的所有键值对都曾经载入结束了。 (5)check\_numcheck\_sum是一个8字节长的无符号整数,保留着一个校验和,这个校验和是程序通过对REDIS、db\_version、databases、EOF四个局部的内容进行计算得出的。服务器在载人RDB文件时,会将载入数据所计算出的校验和与check\_sum所记录的校验和进行比照,以此来查看RDB文件是否有出错或者损坏的状况呈现。 6. 剖析RDB文件咱们应用od命令来剖析Redis服务器产生的RDB文件,该命令能够用给定的格局转存( dump)并打印输人文件。比如说,给定-c参数能够以ASCII编码的形式打印输出文件,给定–x参数能够以十六进制的形式打印输人文件 Linux od命令用于输入文件内容。od指令会读取所给予的文件的内容,并将其内容以八进制字码出现进去。 【数据库为空时的rdb文件】 以后是数据状态为空的RDB文件,所以只包含四局部,1:五个字节的标识位REDIS2:四个字节的版本号:00063:一个字节的EOF常量:377 (ASCII码)4:八个字节的校验和:334 263 C 360 Z 334 362 V 【执行插入命令后的RDB文件】 其中黄色框内示意是整数0,即数据库0有数据其中红色框内:\0 003 msg 005 hello\0示意的是以后数据的类型,0示意的是字符串003示意的msg即Key的长度,005示意的是value的长度msg键,hello示意值

April 10, 2021 · 1 min · jiezi

关于redis:知识总结Redis

概述Redis优缺点长处读写性能优异。反对数据长久化,反对AOF和RDB两种长久化形式。反对事务,Redis的所有操作都是原子性的,同时Redis还反对对几个操作合并后的原子性执行。反对的数据结构丰盛。反对主从复制,主机会主动将数据同步到从机,能够进行读写拆散。毛病数据库容量受到物理内存的限度。Redis 不具备主动容错和复原性能,主机从机的宕机都会导致前端局部读写申请失败,须要期待机器重启或者手动切换前端的IP能力复原。Redis 较难反对在线扩容,在集群容量达到下限时在线扩容会变得很简单。Redis为什么这么快齐全基于内存,绝大部分申请是纯正的内存操作,十分疾速。数据结构简略,对数据操作也简略,Redis 中的数据结构是专门进行设计的。采纳单线程,防止了不必要的上下文切换和竞争条件。应用多路 I/O 复用模型,非阻塞 IO。数据结构Redis反对的数据类型数据类型能够存储的值操作利用场景String字符串、整数、浮点数对整个字符串或者其中一部分进行操作<br/>对整数和浮点数进行自增或者自减操作做简略的键值对缓存List列表从两端压入或弹出元素<br/>对单个或多个元素进行修剪只保留一个范畴内的元素存储一些列表型的数据结构,相似粉丝列表、文章的评论列表之类的数据Hash蕴含键值对的无序散列表增加、获取、移除键值对<br/>获取所有键值对<br/>查看某个键是否存在存储结构化的数据,比方一个对象Set无序汇合查看一个元素是否存在于汇合中<br/>计算交加、并集、差集<br/>从汇合外面随机获取元素能够利用交加把两个人的粉丝列表整一个交加Zset有序汇合依据分值范畴或者成员来获取元素<br/>计算一个键的排名去重但能够排序,如获取排名前几名的用户三种非凡的数据类型: Geospatial(天文空间)。该性能能够推算出地理位置信息,两地之间的间隔。HyperLogLog。是统计基数的利器,用于统计网站的 UV。bitmap(位图)。通过最小的单位 bit 来进行 0 或者 1 的设置。罕用于统计用户信息,比方沉闷粉丝和不沉闷粉丝、登录和未登录、是否打卡等。zset跳表的数据结构利用场景String的利用场景商品编号、订单号采纳INCR(递增)命令生成用INCR记录点赞数文章的阅读数,只有点击了地址,阅读数就加一。hash的利用场景相当于:Map<string, map> 购物车晚期 List的利用场景微信文章订阅公众号 公众号公布了文章别离是11和22。我关注了他们,只有他们公布了新文章,就会装置进我的List:lpush likeauthor:uid9543 11 22查看本人订阅的全副文章,相似分页,上面0~10就是一次性显示10条:lrange likeauthor:uid9543 0 10Set的利用场景微信抽奖小程序 一个用户点击参加按钮:SADD key 用户ID显示曾经有多少人参加:SCARD key抽奖(从set中任意选取N个中奖人) SPOP key 3,随机抽奖3人,元素会删除SRANDMEMBER key 3,随机抽奖3人,元素不删除微信敌人圈点赞,并且显示所有点赞的用户好友的独特关注(交加)可能意识的人(差集)Zset的利用场景依据商品销售对商品进行排序显示(分数是销量)抖音热搜长久化长久化就是把内存的数据写到磁盘中去,避免服务器因为宕机,导致内存数据失落。Redis 反对 RDB(默认) 和 AOF 两种长久化机制,当下次重启时利用之前长久化的文件即可实现数据恢复。 RDB (Redis DataBase) 和 AOF (Append-Only File)RDB:依照肯定的工夫将内存的数据以快照的形式保留到硬盘中,对应产生的数据文件为 dump.rdb,通过配置文件中的save参数来定义快照的周期。 AOF:只追加文件。将Redis执行的每次写命令记录到独自的日志文件中。 优缺点是什么?AOF 每条数据都写入文件中,比 RDB 更平安。然而 AOF 文件比 RDB 文件大,且复原速度慢。RDB 性能比 AOF 好。RDB 应用 fork 子过程来实现写操作,让主过程持续解决命令,使 IO 最大化。如果想数据的安全性更高,应该同时应用两种长久化性能。如果能够接受数分钟以内的数据失落,能够只应用 RDB 长久化。 也不肯定都只应用 AOP,应用 RDB 定时生成 RDB 快照(snapshot)十分便于进行数据库备份。 ...

April 10, 2021 · 2 min · jiezi

关于redis:Redis-的-protectedmode

以下两种状况同时满足时,会触发Redis的protected-mode: 未应用 bind 指令明确配置一组IP地址。未配置明码。当服务器同时存在这两种状况时,客户端(非服务器本机)能够失常连贯。然而进行数据操作时报错: (error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients.解决方案在服务器上应用客户端连贯Redis,运行 “CONFIG SET protected-mode no”命令禁用保护模式。编辑Redis配置文件,将protected-mode 设置为no,而后重启服务器。应用 “--protected-mode no” 选项重启服务器。编辑Redis配置文件,设置绑定地址或验证明码(只须要执行其中一个操作,即可承受内部连贯)。

April 9, 2021 · 1 min · jiezi

关于redis:Redis底层原理

比照另一个驰名的缓存中间件memcached,redis提供了更加丰盛的数据结构和命令,它反对基于列表、汇合、哈希表等多种数据结构。这些构造在redis中是由6种底层数据结构来实现: 简略动静字符串(SDS)链表字典跳跃表整数汇合压缩列表 SDS 用来保留redis数据库中的字符串,它是一个构造体: 构造体中的三个属性别离用来示意已应用的字节数量、未应用的字节数量、字节数组,redis之所以设计这个构造而不应用C语言中的字符串,是因为SDS构造相比C语言中的字符串有如下长处: 记录了字符串的长度,执行strlen操作时,复杂度为O(1),而一般字符串为O(n)。SDS采纳事后调配和惰性开释的优化策略,缩小重新分配空间的次数,其中有free字段记录未应用空间字节数。二进制平安,除了能够存储字符还能够存储任意二进制。SDS操作函数会主动查看空间是否足够并且空间有余时主动扩大空间,从而避免内存溢出。 链表 用来存储链表构造数据,它被用来实现SADD等汇合命令: 字典 字典在Redis中利用十分宽泛,Redis数据库自身就是应用字典来作为底层实现的,比方咱们执行命令:SET msg "hello world",redis就会在数据库中创立一个键为msg值为"hello world"的字典。 字典在实现上蕴含两个hash表,惯例状态下,只有第一个hash表存储数据,当产生rehash时,会给第二个hash表调配空间,并且把第一个hash表中的数据拷贝到第二个hash表中。如果hash表中的数据量比拟大时,会采纳渐进式rehash,分屡次实现,字典中有个rehashindex字段记录rehash进度(如果以后未进行rehash值为-1),这样的话在字典中查问数据时,可能会查找两个hash表,先查第一个表,如果查不到再查第二个,然而新增的数据都会增加到第二个hash表中,产生rehash之后会由第二hash表负责查问客户端申请数据。当服务器正在执行BGSAVE、BGREWRITEAOF等耗CPU的命令时,会尽量避免rehash操作。 跳跃表 redis实现了一个跳跃表构造,跳跃表被用来实现缓存中的有序汇合如ZADD等命令。 整数汇合 当汇合中只蕴含整数时,并且汇合中的元素数量不多时,redis会采纳整数汇合当作底层实现。 其中contents中的元素有可能是16、32、64字节,redis只会调配适合的内存,比方以后增加的时16位的整数,那么只会给contents元素调配16字节,后续往数组中再次增加16字节以上的整数时,会给该数组降级重新分配32或64字节内存,数组只能降级不能降级,能从16字节降级到32或64字节,然而不能从64字节降级到16或32字节。 压缩列表 当列表、汇合、hash表、有序汇合等构造中的元素数量小于某个阀值,redis会采纳压缩列表当作这些构造的底层实现,目标是为了节俭内存,压缩列表蕴含了下列各个组成部分: zlbytes 4字节,纪录整个压缩列表占用的内存字节数:在对压缩列表进行内存重调配,或计算zlend时应用。zltail 4字节,纪录压缩列表表尾节点间隔压缩列表的起始地址有多少个字节,通过这个偏移量程序能够毋庸遍历整个压缩列表就能够确定表尾节点的地址。zllen 2字节,纪录压缩列表蕴含的节点数量,当属性值等于UINT16_MAX时,结点的实在数量须要遍历整个压缩列表能力计算得出。entryX,列表节点,长度由结点中的内存结点,结点中有个字段previous_entry_length记录了前一个几点的长度,当结点的长度在254左右时,对某结点的批改可能会引发所有结点的连锁更新。 压缩列表会节约内存,然而拜访或批改构造中的元素时会损失一些性能,所以当元素数量或者元素大小超过了某个阀值之后会对值对象进行编码转换,转换成汇合、hash表、有序汇合等构造,并从新分配内存。 对象 Redis并没有间接应用下面那些数据结构来实现键值对数据库,而是在这些数据接口的根底上创立了一个对象零碎,每次在Redis数据库中新创建一个键值对时,至多会创立两个对象,一个键对象,一个值对象。每个对象都蕴含指定的类型和编码。 对象类型 对象的type属性设置,能够通过TYPE命令来输入对象的类型,对象有上面几种类型: 字符串对象:类型常量为REDIS_STRING,输入值string。列表对象:类型常量为REDIS_LIST,输入值list。哈希对象:类型常量为REDIS_HASH,输入值hash。汇合对象:类型常量为REDIS_SET,输入值hash。有序汇合表对象:类型常量为REDIS_ZSET,输入值zset。对象编码 对象的encoding属性设置,能够通过OBJECT ENCODING命令查看对象的编码,对象有上面几种编码: long类型整数,REDIS_ENCODING_INT,输入intembstr编码的SDS,REDIS_ENCODING_EMBSTR,输入embstr。embstr编码是专门用于保留短字符串的一种优化编码方式,跟失常的字符编码相比,字符编码会调用两次内存调配函数来别离创立redisObject和sdshdr构造,而embstr编码则通过调用一次内存调配函数来调配一块间断的空间,空间中一次蕴含redisObject和sdshdr两个构造SDS,REDIS_ENCODING_RAW,输入raw字典,REDIS_ENCODING_HT,输入hashtable双端链表,REDIS_ENCODING_LINKEDLIST,输入linkedlist压缩列表,REDIS_ENCODING_ZIPLIST,输入ziplist整数汇合REDIS_ENCODING_INISET,输入intset跳跃表和字典,REDIS_ENCODING_SKIPLIST,输入skiplist每种类型的对象至多应用了两种不同的编码,在不同的条件下redis会对对象进行编码转换,比方如果对象保留的全部都是整数,那么他的编码是int,然而当执行了一些命令之后对象中存储的曾经不全副是整数了,那么会把该对象的编码从int变为raw,其它类型的对象同理。

April 9, 2021 · 1 min · jiezi

关于javascript:一个标准的SpringBoot前后端分离部署手册内置TomcatVueUniapp

SpringBoot我的项目怎么部署?参考我的项目案例:http://github.crmeb.net/u/crmeb 打包前筹备工作 一个主域名,3个子域名共计4个域名 主域名用于拜访挪动端,子域名2用于PC治理后盾,子域名3用于拜访Java Api,子域名4用于图片资源拜访 举例4个域名,下文中会用此来代替 挪动端    --->  https://www.app.comPC 后盾    --->  https://admin.app.comJava Api    --->  https://api.app.com图片资源    --->  https://image.app.comJava 我的项目运行和打包 把Java我的项目导入idea 抉择我的项目中的 crmeb文件夹,也就是Java Api子项目 等我的项目主动载入实现 我的项目配置    依据本人的理论状况配置 shell部署脚本配置   开源不易,我司统计下装置量,只有首次部署会统计,不会有任何影响,请依据本人的具体情况批改下,版本号不须要批改 打包我的项目 看见  BUILD SUCCESS  打包实现 WEB PC 治理端 运行和打包 运行以下命令之前请确认npm环境正确运行 如果开发能够应用webStorem或者Vscode 终端应用本人趁手的命令行工具 cd 到clone我的项目的admin文件夹目录 批改对应环境配置文件 依据本人打包的环境配置Java Api我的项目申请域名 执行装置所需包文件 npm install 打包命令可依据本身需要批改 执行 npm run build:prod   线上环境              build:prod 线上环境 ...

April 8, 2021 · 1 min · jiezi

关于redis:三次给你讲清楚Redis之Redis是个啥

摘要:Redis是一款基于键值对的NoSQL数据库,它的值反对多种数据结构:字符串(strings)、哈希(hashes)、列表(lists)、汇合(sets)、有序汇合(sorted sets)等。本文分享自华为云社区《三次给你聊分明Redis》之Redis是个啥》,原文作者:兔老大。 一、入门Redis是一款基于键值对的NoSQL数据库,它的值反对多种数据结构:字符串(strings)、哈希(hashes)、列表(lists)、汇合(sets)、有序汇合(sorted sets)等。 • Redis将所有的数据都寄存在内存中,所以它的读写性能非常惊人,用作数据库,缓存和音讯代理。 • Redis具备内置的复制,Lua脚本,LRU逐出,事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster主动分区提供了高可用性。 • Redis典型的利用场景包含:缓存、排行榜、计数器、社交网络、音讯队列等 1.1NoSql入门概述1)单机Mysql的美妙时代 瓶颈: 数据库总大小一台机器硬盘内存放不下;数据的索引(B + tree)一个机器的运行内存放不下;访问量(读写混合)一个实例不能接受; 2)Memcached(缓存)+ MySql + 垂直拆分 通过缓存来缓解数据库的压力,优化数据库的构造和索引。 垂直拆分指的是:分成多个数据库存储数据(如:卖家库与买家库)。 3)MySql主从复制读写拆散 主从复制:主库来一条数据,从库立即插入一条;读写拆散:读取(从库Master),写(主库Slave); 4)分表分库+程度拆分+MySql集群 主库的写压力呈现瓶颈(行锁InnoDB取代表锁MyISAM);分库:依据业务相干紧耦合在同一个库,对不同的数据读写进行分库(如注册信息等不常改变的冷库与购物信息等热门库离开);分表:切割表数据(例如90W条数据,id 1-30W的放在A库,30W-60W的放在B库,60W-90W的放在C库); MySql扩大的瓶颈 大数据下IO压力大表构造更改艰难罕用的Nosql RedismemcacheMongdb以上几种Nosql 请到各自的官网上下载并参考应用 Nosql 的外围性能点 KV(存储)Cache(缓存)Persistence(长久化)…… 1.2redis的介绍和特点:问题: 传统数据库:长久化存储数据。solr索引库:大量的数据的检索。在理论开发中,高并发环境下,不同的用户会须要雷同的数据。因为每次申请,在后盾咱们都会创立一个线程来解决,这样造成,同样的数据从数据库中查问了N次。而数据库的查问自身是IO操作,效率低,频率高也不好。总而言之,一个网站总归是有大量的数据是用户共享的,然而如果每个用户都去数据库查问,效率就太低了。 解决: 将用户共享数据缓存到服务器的内存中。 特点: 1、基于键值对2、非关系型(redis)关系型数据库:存储了数据以及数据之间的关系,oracle,mysql非关系型数据库:存储了数据,redis,mdb.3、数据存储在内存中,服务器敞开后,长久化到硬盘中4、反对主从同步 实现了缓存数据和我的项目的解耦。 redis存储的数据特点:大量数据用户共享数据数据不常常批改。查问数据 redis的利用场景:网站高并发的主页数据网站数据的排名音讯订阅 1.3redis——数据结构和对象的应用介绍redis官网 微软写的windows下的redis 咱们下载第一个,而后根本一路默认就行了。 装置后,服务主动启动,当前也不必主动启动。 呈现这个示意咱们连贯上了。 1.3.1 String数据结构 struct sdshdr{ //记录buf数组中已应用字节的数量 int len; //记录buf数组中未应用的数量 int free; //字节数组,用于保留字符串 char buf[];}常见操作 127.0.0.1:6379> set hello worldOK127.0.0.1:6379> get hello"world"127.0.0.1:6379> del hello(integer) 1127.0.0.1:6379> get hello(nil)127.0.0.1:6379>利用场景 ...

April 8, 2021 · 5 min · jiezi

关于数据库:乐观锁

乐观锁的惯例操作select rev from table where id = $idupdate table set name=$name, rev=rev+1 where id = $id and rev=$rev此时有两个线程a和b来批改用户名分成4中状况1、 abselect rev from table where id = $idselect rev from table where id = $idupdate table set name=$name, rev=rev+1 where id = $id and rev=$rev  rev=2 update table set name=$name, rev=rev+1 where id = $id and rev=$rev  失败 abselect rev from table where id = $idselect rev from table where id = $id update table set name=$name, rev=rev+1 where id = $id and rev=$rev  rev=2update table set name=$name, rev=rev+1 where id = $id and rev=$rev  失败 ...

April 7, 2021 · 1 min · jiezi

关于java:分布式场景自定义SpringBoot流程启动器记录

一、应用步骤导入依赖`<dependency> <groupId>com.qianyu</groupId><artifactId>flow-spring-boot-starter</artifactId><version>0.0.1-SNAPSHOT</version></dependency>`

April 7, 2021 · 1 min · jiezi

关于redis:快速学习Redis快速学习

什么是Redis?随着访问量的晋升,关系型数据库多多少少遇到了瓶颈,为了克服这一问题,NoSQL(Not Only SQL)应运而生,它同时具备了高性能、可扩展性强、高可用等长处。 redis是当初受欢迎的NoSQL数据库之一,是由C语言开发的,蕴含多种数据结构,反对网络,基于内存,可选持久性的键值对存储数据库。 Redis特点 * redis反对多种数据结构 * redis通过key-value的模式存储数据 * redis反对数据的长久化 * redis反对主从模式,能够配置集群 * 基于内存运行,性能高效Redis装置附一个官网地址,微妙链接 redis尽管也有Windows版,然而还是举荐在linux零碎下装置。 下载redis.tar.gz包并发送到linux零碎。解压tar包,tar -zxvf redis-6.2.1.tar.gz -C dir。进入解压后的src目录中,执行make命令,此命令编译C,然而须要gcc反对,没有能够应用yum提前下载gcc。 如果编译过程中报错提醒没有gcc反对,在退出编译并装置gcc后须要应用make distclean将之前编译的内容革除。编译胜利之后,执行make install命令将可执行文件拷贝到/usr/local/bin。装置胜利。Redis服务启动次要有以下三种形式 redis-server 前台启动redis,此办法启动后会占用控制台并应用默认配置启动redis服务。redis-server & 后盾启动redis,此办法不会占用控制台,也是应用默认配置启动redis服务。redis-server redis.conf & 后盾应用指定配置文件启动redis,应用指定配置文件中的配置启动redis服务。(配置文件模板为redis根目录的redis.confRedis服务敞开次要有一下两种形式 kill -9 pid 括弧笑。慎用!!!redis-cli shutdown 此办法默认敞开本机上端口为6379的redis服务,如果批改了端口或ip,须要批改为以下格局redis-cli -h ipadress -p port shutdown。Redis客户端redis默认带有客户端为redis-cli 连贯形式为 redis-cli -h ipadress -p port -a password,如果redis装置在本机且端口为默认的6379能够间接应用redis-cli连贯。 退出客户端只须要执行exit命令。 Redis基本知识测试redis服务性能:redis-benchmark命令,参数具体如下表测试客户端与服务端连贯状况:ping命令,须要在客户端中执行,连贯失常返回PONG。查看redis信息:info命令,须要在客户端中执行,也能够在前面加指定内容信息,例info cpu。redis默认创立16个数据库,依据[0,15]编号命名,无奈本人创立,如果有数据库实例数量要求能够通过配置文件批改。客户端默认连贯0号数据库实例,能够应用select index命令切换数据库实例。显示以后数据库实例有多少数据(key的数量)须要在客户端中执行:dbsize命令。清空以后数据库实例,须要在客户端中执行:flushdb。清空所有数据库实例,须要在客户端中执行:flushall。查看配置信息,须要在客户端中执行:config get *,也能够执行某条配置,例config get port。Redis的数据结构redis实质上还是数据库,职能是贮存数据,针对于程序处理后的数据,redis提供了多种数据类型存储。 String特点:单key对应单个value List特点:单key对应多个value,value容许反复且有序(按插入程序排序) Set特点:单key对应多个value,value不容许反复且无序。 Hash特点:单key对应多个filed-value对。 Zset特点:单key对应多个value,每个value对应一个score值,value不容许反复且有序(依照score从小到大排序) Redis的操作命令<font color=red>所有操作命令都在客户端中应用。</font> 对于Key的操作命令keys * 查找所有所有合乎通配符的key。* 匹配一个或多个字符 ? 匹配一个字符 [] 匹配一个字符且字符须要在[]中提前定义。命令返回以后数据库实例中所有key。exists key1 [key2 ...] ...

April 6, 2021 · 3 min · jiezi

关于redis:Redis的5种数据类型的命令下

明天来说剩下三种数据类型的命令,没有看string和list的小伙伴了一番看我上一篇文章呦 Redis的5种数据类型的命令(上) hash类型命令hset key field value 插入或批改键为key的field字段的值为value,不存在则创立,存在则批改hsetnx key field value 插入或批改键为key的field字段的值为value,不存在则创立,存在则失败hgetall key 返回指定key的所有键、值hget key field 返回指定key的field字段的值hmset key field1 value1 field2 value2 ....... 插入多条hmget key filed1 filed2 ...... 返回多个字段的值hkeys key 返回指定key的所有字段hvals key 返回指定key的所有字段的对应的值hstrlen key field 返回指定key的field字段长度,不存则返回0hincrby key field number 对key的dield字段的值与number进行相加,number能够是正、负整数hincrbyfloat key field number 对key的dield字段的值与number进行相加,number能够是正、负小数hdel key field1 field2 ...... 删除指定key的field1......字段hlen key 返回指定key的键值对个数SET类型命令注:相似list,只不过set是无序的,并且能够去重 sadd key value1 value2 ...... 插入键为key的单个或多个元素srem key value1 value2 ...... 删除指定key的单个或多个元素smembers key 返回指定key的所有值交加:sinter key1 key2 ...... 返回这些key的交加sinterstore destkey key1 key2 ...... 将k1、k2....的交加插入到destkey中,如果destkey自身曾经存在元素,则清空并将返回的多个key的交加插入并集:sunion key1 key2 ...... 返回这些key的并集sunionstore destkey key1 key2 ...... 将这些key的并集插入到指定key里差集: ...

April 6, 2021 · 1 min · jiezi

关于redis:干货丨如何用慢查询找到-Redis-的性能瓶颈

转自@twt社区,【作者】姜文浩。 Redis数据库是一个基于内存的 key-value存储系统,当初redis最罕用的应用场景就是存储缓存用的数据,在须要高速读/写的场合应用它疾速读/写,从而缓解利用数据库的压力,进而晋升利用解决能力。 因为Redis的单线程架构,所以须要每个命令能被疾速执行完,否则会存在阻塞Redis的可能,了解Redis单线程命令解决机制是开发和运维Redis的外围之一。 许多数据库会提供慢查问日志帮忙开发和运维人员定位系统存在的慢操作。所谓慢查问日志就是零碎在命令执行前后计算每条命令的执行工夫,当然在数据库中最常见的就是select这些sql语句了,当超过预设阀值,就将这条命令的相干信息(例如:产生工夫,耗时,命令的详细信息)记录下来,Redis也提供了相似的性能。 那么如何应用Redis所提供的慢查问性能呢?Redis次要提供了slowlog-log-slower-than和slowlog-max-len两个配置参数来提供这项性能。两项参数别离用来设置慢查问的阈值以及存加快查问的记录。首先对redis的这两个配置进行一个阐明 : 从字面意思就能够看出,能够通过slowlog-log-slower-than参数设置什么状况下是慢语句,只有redis命令执行工夫大于slowlog-log-slower-than的才会定义成慢查问,才会被slowlog进行记录。它的单位是微秒(1秒=1000毫秒=1000000微秒),在初始状况下默认值是10000,也就是10ms,如果执行了一条比较慢的命令,如果它的执行工夫超过了 10ms ,那么它将被记录在慢查问日志中。(如果slowlog-log-slower-than=0会记录所有的命令,slowlog-log-slower than<0对于任何命令都不会进行记录) 从字面意思看,slowlog-max-len阐明了慢查问日志最多能够存储多少条记录,实际上Redis应用了一个列表来存储慢查问日志,slowlog-max-len就是列表的最大长度,它本身是一个先进先出队列,当slowlog超过设定的最大值后,会将最早的slowlog删除。简而言之当一个新的命令满足慢查问条件时会被插入到这个列表中,当慢查问日志列表已处于其最大长度时,最早插入的一个命令将从列表中移出,例如slowlog-max-len设置为 50 ,当有第51条慢查问插入的话,那么队头的第一条数据就入列,第51条慢查问就会入列。 接下来具体介绍一下如何配置这两个参数,有两种形式进行配置,以下截图全副应用了redis -5.0.5版本 : 形式一:通过配置redis.conf文件进行配置。 通过批改redis .conf文件之后重启redis服务 , 配置即可失效 。 形式二:通过CONFIG命令进行动静配置 配置查问工夫超过1毫秒的命令进行记录保留500条慢查记录 通过config get命令确认配置已失效 要留神通过config命令配置的为动静失效 , 一旦服务重启则会从新复原为默认设置 , 所以倡议在排查问题时通过config这种形式进行配置 , 然而服务稳固后通过批改配置文件形式进行最终确认 (能够通过config rewrite命令长久化到本地文件 , 但要次要启动redis时要指定redis . conf文件 该命令才能够失效)。 相干的参数曾经设置实现了 , 那么如何查看记录的信息呢 ?要想查看所记录的日志 , 次要应用 SLOWLOG GET 或者 SLOWLOG GET number 命令,前者将会输入所有的 slow log ,最大长度取决于 slowlog-max-len 选项的值,而 SLOWLOG GET number 则只打印指定数量的日志。 查看以后日志数量: 应用SHOW LEN命令查看日志数量。 因为我是新装置的redis , 所以当初还没有耗时长日志 , 所以条数是 0,如果日志条数过多,还能够应用slowlog reset命令进行日志清空 。 ...

April 6, 2021 · 1 min · jiezi

关于golang:优雅的写单元测试

简 介置信各位Gopher 在编写代码的时候都离不开编写单元测试,Go语言尽管自带单元测试性能,然而应用起来有点乏味和干燥。在GoConvey诞生之前也呈现了许多第三方辅助库。但没有一个辅助库可能像GoConvey这样优雅地书写代码的单元测试,简洁的语法和舒服的界面可能让一个不爱书写单元测试的开发人员从此爱上单元测试。 GoConvey 是个相当不错的 Go 测试框架,兼容go testing,并且可间接在终端窗口和浏览器上应用。 特 性间接整合 go test丰盛的测试断言规定可读的黑白控制台输入全自动的Web UI疾速体验疾速体验,先看看咱们的代码 func TestSpec(t *testing.T) { Convey("给出一个带有起始值的整数", t, func() { x := 1 Convey("当整数递增时", func() { x++ Convey("该值的后果应是大于>1 ?", func() { So(x, ShouldEqual, 2) }) }) })}而后跑起来:go test -v So函数的第一个参数你本人被测试逻辑函数,第二个参数 断言规定,第三个参数预计后果,能够看到档次清晰,并且兼容go test -v命令。 疾速上手在你的我的项目装置goconvey在Go testing文件外面编写测试代码运行即可看到测试后果在我的项目上面装置goconerygo get github.com/smartystreets/goconvey在我的项目下创立一个operator.go文件,这个文件只是为了演示单元测试应用的例子operator.go文件 package testingimport( "errors")// 为了测试编写的加减乘除函数func Add(x,y int) int { return x + y}func Subtract(x,y int) int { return x - y}func Division(x,y int)(int,error){ if y == 0 { return 0,errors.New("被除数不能为零") } return x / y,nil}func Multiply(x,y int) int{ return x * y}创立一个单元测试并且应用goconery进行单元测试operator_test.go文件 ...

April 6, 2021 · 2 min · jiezi

关于java:不懂缓存一致性易把代码写成Bug

哈喽哈喽大家猴,我是把代码写成bug的大头菜。公众号:大头菜技术(bigheadit)。原创不易,但欢送转载。本文次要分享一下对于缓存一致性问题和其解决方案。上面是本文的次要目录,大家能够挑着看。 目录什么是缓存一致性为什么要保障缓存一致性如何保障缓存一致性如何做到强一致性总结01 什么是缓存一致性就是缓存和数据库的数据不统一导致的问题,缓存一致性分为强一致性和最终一致性。 强一致性,这个比拟损耗性能,比较复杂,退出之后,可能会比没加缓存更慢。最终一致性,是容许缓存数据和数据库数据一段时间内不统一,但数据最终会保持一致。这个性能较高。02 为什么要保障缓存一致性因为业务中存在一些写操作导致的,是要先写缓存,还是先写数据库。二者程序的不同会导致不同的问题。 单纯的读操作,是不会导致缓存一致性问题的,因为读是幂等的哈。读无数次都是不会变的,因而就不存在读操作引起缓存一致性问题。 因而导致缓存不统一的就是写操作了。写操作是导致缓存不统一的起因。但这不是要保障缓存一致性的理由,归根结底都是业务须要,如果业务需要容许缓存和数据库的不统一,那就不须要保障缓存一致性了。 03 如何保障缓存一致性(解决方案)置信很多人都晓得经典计划:cache aside pattern。 首先明确的是,读不会产生缓存一致性问题。是写操作,才会产生缓存一致性问题。 第一点,生效:申请过去时,先拜访缓存,缓存不存在,再去拜访数据库,更新缓存。 第二点,读:申请过去时,缓存中有数据,间接返回数据。 第三点,写:先更新数据库,后删除缓存。 要害在第三点,前提,数据库必定是更新的。剩下的问题就是:是要更新缓存?还是要删除缓存?是先对数据库操作?还是先对缓存操作?俩俩组合有4种可能性: 先更新缓存,后更新数据库先更新数据库,后更新缓存先删除缓存,后更新数据库先更新数据库,后删除缓存1.先更新缓存,后更新数据库首先咱们要明确,更新数据库或者更新缓存,都面临着更新失败的危险。但在互联网高并发的环境中和依据墨菲定律,这个事是肯定会产生的。 先更新缓存,胜利了后更新数据库,失败了,当然你会说重试,好,那我就重试N次,但如果数据库彻底挂了,复原不了了,重试也没用导致问题:数据失落,数据库外面的数据还是老数据2.先更新数据库,后更新缓存假如有两个申请,A申请是更新,B申请是更新,A先B后,但二者距离很短 线程A更新了数据库线程B更新了数据库线程B更新了缓存线程A更新了缓存导致问题:缓存中是旧数据,数据库中是新数据,这就不统一了。还有就是更新后的缓存,真的会被再读取吗?如果缓存数据不再被读取,那就白白操作了一次缓存更新操作。并且还占用内存空间。依据这个例子,能够看出,更新缓存是不可取的,那就间接删除缓存吧。接着看 3.先删除缓存,后更新数据库假如有两个申请,A申请是更新,B申请是读,可能呈现的问题 线程A删除缓存线程B查问不到缓存,间接去数据库查旧值线程A将新值写入数据库线程B更新缓存导致问题:缓存中的是旧值,数据库中的是新值,二者不统一。进一步,如果数据库存在读写拆散,那么缓存和数据库数据不统一的状况进一步加剧。线程A删除缓存线程A将新值写入主数据库,但未同步数据到从数据库线程B查问不到缓存,间接去从数据库查,查到旧值线程B更新缓存新数据同步到从数据库导致问题:缓存是旧值,数据库是新值,二者数据不统一4.先更新数据库,后删除缓存假如有两个申请,A申请是读,B申请是更新,可能会呈现的问题 缓存刚好生效线程A查数据库,失去旧值线程B更新数据库线程B删除缓存线程A更新缓存导致问题:缓存是旧值,数据库是新值,二者不统一。但这种状况的可能性相对来说比拟小,因为须要缓存刚好生效,并且此时有一个线程去读,且刚好又有一个写的线程。而且写的线程实践上是比读的线程慢的,因为写的线程,须要加锁。而查问不必加锁,不包含简单的查问。在数据库读写拆散的状况下,这种状况会更加显著: 线程B更新主库线程B删除缓存线程A查问缓存,没有命中,查问从库失去旧值数据同步到从库线程A更新缓存导致问题:缓存数据和数据库数据不统一如果思考更新数据库或者更新缓存失败的话,那么更新数据库失败的话,其实数据库和缓存都是旧数据,因而不存在数据不统一的状况。 如果更新缓存失败,那么有过期工夫来保障最终一致性。如果非要较真的话,能够退出重试机制。 重试机制能够用线程池,也能够用MQ。MQ更加牢靠。能够间接订阅MySQL的binlog,来触发缓存的删除。当然,其实MQ也会挂。然而MQ和缓存都一起挂的几率,应该很小吧。 综上所述四种状况 尽管每种计划都有各自的问题,但呈现几率较小的是先更新数据库,后删除缓存计划。为什么先更新数据库?因为数据库的长久化能力比缓存好。上述四种状况,还可能呈现缓存并发,缓存穿透,缓存雪崩的问题。这些问题,这里就不探讨了。感兴趣的话,本人去看我的相干文章。 04 如何做到强一致性计划一:分布式事务能够用分布式事务,分布式事务,具体的实现有2PC、3PC、音讯队列等。如果要采纳这个计划,架构设计中要引入很多容错、回退、兜底的措施。业务代码就减少复杂性了。还有人说用分布式一致性算法paxos和raft,这就更简单了。 计划二:分布式读写锁首先,咱们回到先更新数据库,后删除缓存 ,要明确什么时候会呈现脏数据? 呈现脏数据:更新数据库后,删除缓存之前。这时候二者数据是不统一的。 如果实现更新数据库时,所有读申请都被阻塞。这就解决了数据不统一的问题,这其实是串行化思路。但结果,当然是性能下滑。 总结其实抉择数据的强一致性和数据的最终一致性。得看具体需要,我如同说了一句废话。然而放弃强一致性,意味着咱们零碎的性能失去肯定水平的晋升。相同,如果咱们谋求强一致性,那就会巨简单,而且可能得失相当,可能性能比不加缓存时还低。缓存这货色,想要用得好,就须要好好推敲,比方过期工夫的设置,长久化,故障复原,空间和工夫的均衡,一致性的抉择,这些都要好好斟酌,没有最好的计划,只有适合的计划。

April 6, 2021 · 1 min · jiezi

关于数据库:生活中的这些难题数据库开发者可为你解决

摘要:开发者们相熟的数据库,对普通人来说可能感知甚少,然而它的用途却无处不在。它能解决咱们生存中的哪些难题呢?还有,做数据库开发凭什么这么吃香?别着急,马上你就有答案了!本文分享自华为云社区《HDC.Cloud2021|生存中的这些难题,华为云数据库开发者为你解决!》,原文作者:神思胖。 随着智能时代的减速演进,这一代开发者十分有幸,能够使用各种翻新技术给世界带来更大的扭转。 开发者们相熟的数据库,对普通人来说可能感知甚少,然而它的用途却无处不在。它能解决咱们生存中的哪些难题呢?还有,做数据库开发凭什么这么吃香?别着急,马上你就有答案了! 狭义上,数据库是存储数据的货色,相似书本、大脑、图书馆;广义上,数据库是存储在计算机中结构化的表格,用户账户信息表、网购订单表、地理位置表…… 别以为数据库跟你没关系,你在华为商城抢购Mate40,你应用网银APP转账交易,数据库都在默默时刻守护您的每一笔交易平安迅捷。 随着新时代下数字化转型减速,数据量越来越大,传统数据库存在瓶颈,于是,华为云数据库就闪亮退场了。 咱们以华为云GaussDB(for Redis)为例,来聊聊数据库开发者能解决生存中哪些常见问题。 1、社交软件无差错通信在咱们日常的即时通讯场景中,实时无差错通信是必要要求。家喻户晓,Redis Stream是一种新的数据类型,它提供了音讯的落地存储性能。Redis Stream作为通信的中间件,可实现聊天室的发言以及信息查看,无论离线在线用户都可屡次查看历史音讯。华为云GaussDB(for Redis)让聊天更有序,让通信更残缺。 2、解决医疗信息孤岛在医疗场景中,集体衰弱信息孤岛亟需解决。Redis Stream能够助力智慧医疗系统实现信息同步,岂但能够记录集体体检报告、诊断报告、用药信息,还能够助力不同医院查问同一个患者的医疗信息。GaussDB(for Redis)解决信息孤岛,更好捍卫衰弱。 3、避免流量洪峰降临零碎解体在常见的双11秒杀流动或团购场景中,通常短时间内有大量的流量,导致系统解体。所有的申请都有一个先后顺序,开发者同样采纳Redis Stream作为中间件,将音讯转存到音讯队列间接提供给利用,能够避免大流量冲击导致的零碎解体,华为云GaussDB(for Redis)让购物更加顺畅。 4、实时查问外卖小哥配送间隔点外卖时你是如何获取外卖小哥的配送间隔的呢?在用户下完外卖订单后,数据库开发者应用geoadd命令退出骑手的地位,还能够应用geodist命令获取骑手的间隔。华为云GaussDB(for Redis)让送餐间隔不再边远。 5、房源地位查问从到衣食住行到买房等人生大事,华为云GaussDB(for Redis)均可助你一臂之力。在泛滥的房源App中,将新的房源退出房源平台中,数据库开发者应用geoadd命令,增加新房源的地位,应用geodist命令,用户可取得与房源的间隔。华为云GaussDB(for Redis)让你与舒适的家更近一步。 作为数据库开发者,小到助力咱们抢购车票、外卖点餐,大到买房、集体医疗信息建档等,哪里有须要哪里都有开发者的身影。他们通过一行行寒冷的代码,解决了生存中的一个个难题,也成就了每个开发者的英雄梦。 作为华为ICT基础设施业务面向寰球开发者的年度盛会,华为开发者大会2021(Cloud)将于2021年4月24日-26日在深圳举办。本届大会以#每一个开发者都了不起#为主题,将汇聚业界大咖、华为科学家、顶级技术专家、天才少年和泛滥开发者,独特探讨和分享云、计算、人工智能等最新ICT技术在行业的深度翻新和利用。智能时代,每一个开发者都在发明裹足不前的奔流时代。世界有你,了不起! 点击链接,理解大会详细信息。https://developer.huaweicloud.com/HDC.Cloud2021.html 点击关注,第一工夫理解华为云陈腐技术~

April 6, 2021 · 1 min · jiezi

关于docker:使用Docker安装部署redis配置文件启动

装置Docker自己电脑为mac,间接下载docker dmg文件 获取redis镜像bind 127.0.0.1 #正文掉这部分,这是限度redis只能本地拜访protected-mode no #默认yes,开启保护模式,限度为本地拜访daemonize no#默认no,改为yes意为以守护过程形式启动,可后盾运行,除非kill过程,改为yes会使配置文件形式启动redis失败databases 16 #数据库个数(可选),我批改了这个只是查看是否失效。。dir ./ #输出本地redis数据库寄存文件夹(可选)appendonly yes #redis长久化(可选)logfile "access.log"requirepass 123456(设置成你本人的明码)

April 3, 2021 · 1 min · jiezi

关于redis:Redis主从复制及其原理

为什么要有主从复制为了防止服务的单点故障,通过给主从复制能够把数据复制多个正本放在不同的服务器上,领有数据正本的服务器能够用于解决客户端的读申请,扩大整体的性能 Redis的主从复制搭建筹备3台机器,主服务器ip为192.168.1.50,从服务器ip为192.168.1.60,192.168.1.70,端口号均为63791.批改redis.conf配置文件 * 3台redis都设置为后盾运行 `daemonize yes`* 2台从服务器增加(若命令行来复制的话,重启之后会有效) `slaveof 192.168.1.50 6379` 2.启动3台redisredis-server /opt/redis-3.0.7/redis.conf 3.客户端连贯redis ./redis-cli 127.0.0.1:6379> pingPONG4.应用info replication命令查看主从关系 192.168.1.50:6379> info replicationReplicationrole:masterconnected_slaves:2slave0:ip=192.168.1.60,port=6379,state=online,offset=823,lag=1slave1:ip=192.168.1.70,port=6379,state=online,offset=837,lag=0master_repl_offset:837repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:836192.168.1.60:6379> info replicationReplicationrole:slavemaster_host:192.168.1.50master_port:6379master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:893slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0192.168.1.70:6379> info replicationReplicationrole:slavemaster_host:192.168.1.50master_port:6379master_link_status:upmaster_last_io_seconds_ago:3master_sync_in_progress:0slave_repl_offset:767slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0a.在主服务器中写入数据,而后能够在其余的从服务器中读取数据 192.168.1.50:6379> set test 'Hello World'OK192.168.1.60:6379> get test"Hello World"192.168.1.70:6379> get test"Hello World"b.从服务器中写入数据,会提醒不能在只读的从服务器中写入数据 192.168.1.60:6379> set test2 hello(error) READONLY You can't write against a read only slave.主从复制原理Redis的主从复制过程大体上分3个阶段:建设连贯、数据同步、命令流传 建设连贯从服务器收回slaveof命令之后,依据主服务器的ip地址和端口建设连贯 数据同步在主从服务器建设连贯确认各自身份之后,就开始数据同步,从服务器向主服务器发送PSYNC命令,执行同步操作,并把本人的数据库状态更新至主服务器的数据库状态Redis的主从同步分为: 全量同步有两种状况下是残缺重同步,一是slave连贯上master第一次复制的时候;二是如果当主从断线,从新连贯复制的时候有可能是残缺重同步全量同步的步骤: 从服务器连贯主服务器,发送SYNC命令主服务器接管到SYNC命名后,开始执行bgsave命令生成RDB文件并应用缓冲区记录尔后执行的所有写命令主服务器bgsave执行完后,向所有从服务器发送快照文件,并在发送期间持续记录被执行的写命令从服务器载入RDB文件,同步执行来自主服务器缓冲区的写命令增量同步用于网络中断等状况后的复制,只将中断期间主服务执行的写命令发送给从服务器只能执行全量同步的状况:1.当主从服务器offset的差距过大超过复制积压缓冲区长度时,将无奈执行局部复制,只能执行全量同步2.主从服务器首次复制时,主服务器将本人的runid发送给从服务器,从服务器将这个runid保存起来;当断线重连时,从服务器会将这个runid发送给主服务器;主服务器依据runid判断是否进行局部复制,如果不统一,只能执行全量同步 命令流传当实现数据同步之后,主从服务器的数据临时达到统一状态,当主服务器执行了客户端的写命令之后,主从的数据便不再统一。为了可能使主从服务器的数据放弃一致性,主服务器会对从服务器执行命令流传操作,即每执行一个写命令就会向从服务器发送同样的写命令

April 3, 2021 · 1 min · jiezi

关于redis:Redis-高可用篇你管这叫-Sentinel-哨兵集群原理

概要咱们晓得「主从复制是高可用的基石」,从库宕机仍然能够将申请发送给主库或者其余从库,然而 Master 宕机,只能响应读操作,写申请无奈再执行。 所以主从复制架构面临一个严厉问题,主库挂了,无奈执行「写操作」,无奈主动抉择一个 Slave 切换为 Master,也就是无奈故障主动切换。 深夜与女朋友么么哒……(此处省略 10000 字),忽然宕机,总不能提起裤子从床上爬起来手工进行主从切换,再告诉其余程序员把地址从新改成新主库上线。 如此一折腾本人已被女友切换成前男友了,万万使不得。所以咱们必须有一个高可用的计划,为此,Redis 官网提供一个高可用计划——哨兵(Sentinel)。 开篇寄语技术的迭代十分的快,然而从技术中积淀下来的思维却是受害终生的。所以不要放心什么中年危机,那些放心中年危机的人通常很难成长起来。只有咱们成长,只有咱们的认知在一直冲破,就不必放心中年危机,这个世界始终是须要那些优秀人才的。什么是哨兵(Sentinel)65 哥:码哥,尽管我没女朋友,然而,防患未然我要把握这个哨兵模式,避免当深夜与女朋友么么哒被打搅,你快说说哨兵的实现原理吧。搭建实例采纳三个哨兵造成集群,三个数据节点(一主两从)形式搭建,如下图所示: 哨兵集群的搭建演示就不在这里赘述了,须要的读者敌人可点击左下角的「浏览原文」查看。 65 哥你听过「武当派」创始人张三疯么?Redis 主从架构就好比一个武当,掌门人就是 Master。掌门人如果挂了,须要从武当七侠外面选举能人担当掌门人。这就须要一个部门能监控掌门人的生死和武当其余弟子的生命状态,并且可能通过投票从武当弟子中选举一个能者负责新掌门,接着再举办新闻发布会向世界发表新掌门的信息。这个「部门」就是哨兵。 哨兵在选举新掌门会遇到以下几个问题: 如何判断掌门真的挂了,有可能假死;到底抉择哪一个武当子弟作为新掌门?通过新闻发布会将新掌门的相干信息告诉到所有武当弟子(slave 和 master)和整个武林(客户端)。哨兵部门次要负责的工作是:监控整个武当、抉择新掌门,告诉整个武当和整个武林。 哨兵机制的次要工作哨兵是 Redis 的一种运行模式,它专一于对 Redis 实例(主节点、从节点)运行状态的监控,并可能在主节点产生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 零碎的可用性。联合 Redis 的 官网文档,能够晓得 Redis 哨兵具备的能力有如下几个: 监控:继续监控 master 、slave 是否处于预期工作状态。主动切换主库:当 Master 运行故障,哨兵启动主动故障复原流程:从 slave 中抉择一台作为新 master。告诉:让 slave 执行 replicaof ,与新的 master 同步;并且告诉客户端与新 master 建设连贯。哨兵也是一个 Redis 过程,只是不对外提供读写服务,通常哨兵要配置成单数,为啥呢?且听「码哥字节」缓缓剖析。 65 哥:那到底「哨兵」这个神秘部门是如何实现这三个能力的?咱们先从全局观看哨兵,简要的理解整个运作流程,接着再针对每一个工作详细分析。首先从监控开始…... 监控Sentinel 只是武当弟子中的非凡部门,在默认状况下,Sentinel 通过飞鸽传书以每秒一次的频率向所有武当弟子、掌门与哨兵(包含 Master、Slave、其余 Sentinel 在内)发送 PING 命令,如果 slave 没有在在规定工夫内响应「哨兵」的 PING 命令,「哨兵」就认为这哥们可能嗝屁了,就会将他记录为「下线状态」; ...

April 2, 2021 · 3 min · jiezi

关于redis:Redis主从架构的搭建

1、主从架构的搭建1.1 master节点的搭建redis但节点的搭建在后面Redis单机装置(生产环境配置)中曾经有具体的的步骤了在这就不多说了。 1.2 slave节点的搭建首先还是把redis节点依照master节点搭建配置好但先别着急启动还须要一些额定的配置批改/etc/redis/6379.conf: #配置master节点的IP和端口号replicaof <masterhost> <masterip>#如果master开启了TCL这里须要配置上口令masterauth password#设置为只读模式replica-read-only yes配置实现后启动先启动master几点,在启动slave节点,既能够了。 ⚠️:1、防火墙关上相应的端口确保端口和网络畅通 2、如果master开启了拜访口令,slave也须要开启并配置雷同的口令

April 2, 2021 · 1 min · jiezi

关于redis:Docker安装LNMPubuntu1804nginx114mysql57php73

Docker镜像筹备拉取ubuntu18.04镜像docker pull ubuntu18.04启动ubuntu容器docker run -it --name="php7.3" --privileged=true ubuntu:18.04 /bin/bashubuntu更换阿里云源备份源mv /etc/apt/sources.list /etc/apt/sources.list.bak更换源 echo -e "deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe \n deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse \n deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse \n deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse \n deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse \n deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse \n deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse \n deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse \n deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse \n deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse" >> /etc/apt/sources.list更新源apt-get update装置罕用的软件软件装置过程中遇到:Do you want to continue? [Y/n]对立输出y而后回车 ...

April 2, 2021 · 2 min · jiezi

关于mysql:用MySQL设计表的时候你会用UUID做主键吗

前言在mysql中设计表的时候,mysql官网举荐不要应用uuid或者不间断不反复的雪花id(long形且惟一,单机递增),而是举荐间断自增的主键id,官网的举荐是auto_increment,那么为什么不倡议采纳uuid,应用uuid到底有什么害处? 关注公众号:北游学Java,支付500页MySQL学习笔记。 对于MySQL的知识点总结了一个思维导图分享给大家 上传上来的图可能有点不清晰,须要高清脑图的同样能够关注公众号支付 一、mysql和程序实例1.1.要阐明这个问题,咱们首先来建设三张表别离是user_auto_key,user_uuid,user_random_key,别离示意主动增长的主键,uuid作为主键,随机key作为主键,其它咱们齐全放弃不变. 依据控制变量法,咱们只把每个表的主键应用不同的策略生成,而其余的字段齐全一样,而后测试一下表的插入速度和查问速度: 注:这里的随机key其实是指用雪花算法算进去的前后不间断不反复无规律的id:一串18位长度的long值id主动生成表: 用户uuid表 随机主键表: 1.2.光有实践不行,间接上程序,应用spring的jdbcTemplate来实现增查测试:技术框架:springboot+jdbcTemplate+junit+hutool,程序的原理就是连贯本人的测试数据库,而后在雷同的环境下写入等同数量的数据,来剖析一下insert插入的工夫来进行综合其效率,为了做到最实在的成果,所有的数据采纳随机生成,比方名字、邮箱、地址都是随机生成。 `package com.wyq.mysqldemo;import cn.hutool.core.collection.CollectionUtil;import com.wyq.mysqldemo.databaseobject.UserKeyAuto;import com.wyq.mysqldemo.databaseobject.UserKeyRandom;import com.wyq.mysqldemo.databaseobject.UserKeyUUID;import com.wyq.mysqldemo.diffkeytest.AutoKeyTableService;import com.wyq.mysqldemo.diffkeytest.RandomKeyTableService;import com.wyq.mysqldemo.diffkeytest.UUIDKeyTableService;import com.wyq.mysqldemo.util.JdbcTemplateService;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.util.StopWatch;import java.util.List;@SpringBootTestclass MysqlDemoApplicationTests {    @Autowired    private JdbcTemplateService jdbcTemplateService;    @Autowired    private AutoKeyTableService autoKeyTableService;    @Autowired    private UUIDKeyTableService uuidKeyTableService;    @Autowired    private RandomKeyTableService randomKeyTableService;    @Test    void testDBTime() {        StopWatch stopwatch = new StopWatch("执行sql工夫耗费");        /**         * auto_increment key工作         */        final String insertSql = "INSERT INTO user_key_auto(user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?)";        List<UserKeyAuto> insertData = autoKeyTableService.getInsertData();        stopwatch.start("主动生成key表工作开始");        long start1 = System.currentTimeMillis();        if (CollectionUtil.isNotEmpty(insertData)) {            boolean insertResult = jdbcTemplateService.insert(insertSql, insertData, false);            System.out.println(insertResult);        }        long end1 = System.currentTimeMillis();        System.out.println("auto key耗费的工夫:" + (end1 - start1));        stopwatch.stop();        /**         * uudID的key         */        final String insertSql2 = "INSERT INTO user_uuid(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";        List<UserKeyUUID> insertData2 = uuidKeyTableService.getInsertData();        stopwatch.start("UUID的key表工作开始");        long begin = System.currentTimeMillis();        if (CollectionUtil.isNotEmpty(insertData)) {            boolean insertResult = jdbcTemplateService.insert(insertSql2, insertData2, true);            System.out.println(insertResult);        }        long over = System.currentTimeMillis();        System.out.println("UUID key耗费的工夫:" + (over - begin));        stopwatch.stop();        /**         * 随机的long值key         */        final String insertSql3 = "INSERT INTO user_random_key(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";        List<UserKeyRandom> insertData3 = randomKeyTableService.getInsertData();        stopwatch.start("随机的long值key表工作开始");        Long start = System.currentTimeMillis();        if (CollectionUtil.isNotEmpty(insertData)) {            boolean insertResult = jdbcTemplateService.insert(insertSql3, insertData3, true);            System.out.println(insertResult);        }        Long end = System.currentTimeMillis();        System.out.println("随机key工作耗费工夫:" + (end - start));        stopwatch.stop();        String result = stopwatch.prettyPrint();        System.out.println(result);    }` 1.3.程序写入后果user_key_auto写入后果: user_random_key写入后果: user_uuid表写入后果: 1.4.效率测试后果 在已有数据量为130W的时候:咱们再来测试一下插入10w数据,看看会有什么后果: 能够看出在数据量100W左右的时候,uuid的插入效率垫底,并且在后序减少了130W的数据,uudi的工夫又直线降落。 工夫占用量总体能够打出的效率排名为:auto_key>random_key>uuid,uuid的效率最低,在数据量较大的状况下,效率直线下滑。那么为什么会呈现这样的景象呢?带着疑难,咱们来探讨一下这个问题: 二、应用uuid和自增id的索引构造比照2.1.应用自增id的内部结构自增的主键的值是程序的,所以Innodb把每一条记录都存储在一条记录的前面。当达到页面的最大填充因子时候(innodb默认的最大填充因子是页大小的15/16,会留出1/16的空间留作当前的批改): ①下一条记录就会写入新的页中,一旦数据依照这种程序的形式加载,主键页就会近乎于程序的记录填满,晋升了页面的最大填充率,不会有页的节约 ②新插入的行肯定会在原有的最大数据行下一行,mysql定位和寻址很快,不会为计算新行的地位而做出额定的耗费 ③缩小了页决裂和碎片的产生 2.2.应用uuid的索引内部结构因为uuid绝对程序的自增id来说是毫无法则可言的,新行的值不肯定要比之前的主键的值要大,所以innodb无奈做到总是把新行插入到索引的最初,而是须要为新行寻找新的适合的地位从而来调配新的空间。 这个过程须要做很多额定的操作,数据的毫无程序会导致数据分布散乱,将会导致以下的问题: ①写入的指标页很可能曾经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取指标页到内存中,这将导致大量的随机IO ②因为写入是乱序的,innodb不得不频繁的做页决裂操作,以便为新的行调配空间,页决裂导致挪动大量的数据,一次插入起码须要批改三个页以上 ③因为频繁的页决裂,页会变得稠密并被不规则的填充,最终会导致数据会有碎片 在把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)当前,有时候会须要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又须要肯定的工夫耗费。 论断:应用innodb应该尽可能的按主键的自增程序插入,并且尽可能应用枯燥的减少的聚簇键的值来插入新行 2.3.应用自增id的毛病那么应用自增的id就齐全没有害处了吗?并不是,自增id也会存在以下几点问题: ①他人一旦爬取你的数据库,就能够依据数据库的自增id获取到你的业务增长信息,很容易剖析出你的经营状况 ②对于高并发的负载,innodb在按主键进行插入的时候会造成显著的锁争用,主键的上界会成为争抢的热点,因为所有的插入都产生在这里,并发插入会导致间隙锁竞争 ③Auto_Increment锁机制会造成自增锁的争夺,有肯定的性能损失 附:Auto_increment的锁争抢问题,如果要改善须要调优innodb_autoinc_lock_mode的配置三、总结本文首先从开篇的提出问题,建表到应用jdbcTemplate去测试不同id的生成策略在大数据量的数据插入体现,而后剖析了id的机制不同在mysql的索引构造以及优缺点,深刻的解释了为何uuid和随机不反复id在数据插入中的性能损耗,具体的解释了这个问题。 在理论的开发中还是依据mysql的官网举荐最好应用自增id,mysql博大精深,外部还有很多值得优化的点须要咱们学习。

April 1, 2021 · 1 min · jiezi

关于java:spring-cloud-采用nacos作为注册中心动态配置redisson

需要对于spring-boot整合redisson的相干计划网上有很多,次要是通过redisson-spring-boot-starter实现主动拆卸,现有的我的项目采纳spring-cloud,nacos作为服务的发现和注册核心,redis的相干配置信息不在本地保留,集中放到配置核心,我的项目启动时从配置核心读取配置文件,构建对应的SingleServerProperties,截止本文的公布,redisson-spring-boot-starter依然不能很好的反对从nacos读取属性实现配置(起因在于:SingleServerProperties须要的配置信息无奈通过繁多的POJO形容,其中的局部属性依赖其它的bean,必须从最小的单元拆卸,最初整合装配成); <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.13.3</version></dependency>SingleServerProperties.java @Bean(destroyMethod="shutdown")RedissonClient redissonClient(SingleServerProperties properties) throws IOException { ObjectMapper mapper=new ObjectMapper(); String jsonString = mapper.writeValueAsString(properties); Config config = Config.fromYAML(jsonString); if (StrUtil.isEmpty(properties.getSingleServerConfig().getPassword())){ config.useSingleServer().setPassword(null); } return Redisson.create(config);}解决思路拆分SingleServerProperties,合成到最小单元(所有的属性均是根底类型,不再依赖其余的bean),从最小的单元拆卸,最初整合装配成SingleServerProperties参考SingleServerProperties的源码,重写该局部BaseConfig.java @Datapublic class BaseConfig<T extends org.redisson.config.BaseConfig<T>> { /** * If pooled connection not used for a <code>timeout</code> time * and current connections amount bigger than minimum idle connections pool size, * then it will closed and removed from pool. * Value in milliseconds. */ @Value("${redisson.singleServerConfig.idleConnectionTimeout:}") private int idleConnectionTimeout = 10000; /** * Timeout during connecting to any Redis server. * Value in milliseconds. */ @Value("${redisson.singleServerConfig.connectTimeout:}") private int connectTimeout = 10000; /** * Redis server response timeout. Starts to countdown when Redis command was succesfully sent. * Value in milliseconds. */ @Value("${redisson.singleServerConfig.timeout:}") private int timeout = 3000; @Value("${redisson.singleServerConfig.retryAttempts:}") private int retryAttempts = 3; @Value("${redisson.singleServerConfig.retryInterval:}") private int retryInterval = 1500; /** * Password for Redis authentication. Should be null if not needed */ @Value("${redisson.singleServerConfig.password:}") private String password; private String username; /** * Subscriptions per Redis connection limit */ @Value("${redisson.singleServerConfig.subscriptionsPerConnection:}") private int subscriptionsPerConnection = 5; /** * Name of client connection */ @Value("${redisson.singleServerConfig.clientName:}") private String clientName; private boolean sslEnableEndpointIdentification = true; private SslProvider sslProvider = SslProvider.JDK; private URL sslTruststore; private String sslTruststorePassword; private URL sslKeystore; private String sslKeystorePassword; private int pingConnectionInterval; private boolean keepAlive; private boolean tcpNoDelay;}Codec.java ...

March 30, 2021 · 2 min · jiezi

关于redis:Windows环境下安装Redis

1 下载安装Redis1.1 下载地址Github地址:https://github.com/MicrosoftArchive/redis/releases 目前微软官网Github只更新到3.2.100版本(2016年7月1日最初一次更新)。如果感觉版本比拟低,上面地址可下载更高的版本(由tporadowski在保护)。 Github地址:https://github.com/tporadowski/redis/releases 1.2 装置步骤关上安装文件,点击“Next”; 勾选批准承受协定条款,点击“Next”; 批改装置门路(默认装置在C盘,看集体爱好批改,自己比拟喜爱装置在D盘),点击“Next”; 批改Redis服务端口(默认端口6379),点击“Next”; 是否设置内存下限(倡议不设置,不在乎那一点内存),点击“Next”; 点击“Install”,实现装置。 2 Redis开启明码认证关上系统资源管理器,切换到Redis装置门路,关上“redis.windows-service.conf”文件(Note:装置目录下有两个配置文件,“redis.windows-service.conf”是对应windows服务的配置文件,“redis.windows.conf”是通过命令行启动Redis对应的配置文件) 搜寻requirepass关键字,批改Redis受权明码(Note:默认配置项前为“#”示意该配置项时正文状态。去掉“#”,输出明码即可。) 重启Redis服务

March 30, 2021 · 1 min · jiezi

关于redis:Windows环境下搭建Redis集群

最近因我的项目须要搭建Redis集群。查找了一些相干博文和材料,踩了不少坑。上面是自己总结的Redis集群搭建步骤和搭建过程中遇到的坑,心愿对大家有帮忙。篇幅有点长,请急躁看。 1   下载安装RedisRedis下载地址:https://github.com/MicrosoftArchive/redis/releases 装置过程比较简单,根本都是默认选项,不在赘述。能够自定义批改装置目录。(自己习惯性装置在D:Program Files目录下。) 2   创立Redis集群节点Reids集群工作至多须要6个节点: 其中3个为主节点, 其余3个是各个主节点的从节点。主节点解体,从节点会主动被推选为主节点,代替主节点工作。 因自己条件无限,只能在一台机器上模仿6个Redis节点,别离对应地址和端口如下: 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 (Note:生产环境下,每个节点须要部署在独立的服务器上。如果部署在一台服务器上,那么只有服务器宕机,整个集群就无奈失常工作,不具备高可用性。) 2.1   配置节点装置实现后,创立文件目录D:RedisCluster,同时创立6个Redis节点文件夹(以端口命名,不便记忆而已)。 复制D:Program FilesRedis目录下所有文件到D:RedisCluster6380目录下。配置6380节点。将redis.windows-service.conf文件重命名为redis.windows-service.6380.conf(重命名是为了不便辨别,不重命名应该也能够)。批改配置项如下: port 6380loglevel noticeappendonly yesappendfilename "appendonly.6380.aof"cluster-enabled yescluster-config-file nodes.6380.confcluster-node-timeout 15000cluster-slave-validity-factor 10cluster-migration-barrier 1cluster-require-full-coverage yes (其余节点依照上述步骤配置,上述配置项中6380全副改为对应节点端口号即可,其余配置项保持一致) 2.2 装置节点服务配置实现后,须要将6个节点注册成服务。在6380节点目录下(即:D:RedisCluster6380)关上CMD,运行如下命令: redis-server --service-install D:RedisCluster6380redis.windows-service.6380.conf --service-name Redis6380 排坑一:原本筹备将Redis节点放在Redis装置目录下(即:D:Program FilesRedis),然而因为全门路蕴含Program Files文件夹,两头有空格,导致在运行上述指令时,总是报错: Invalid argument during startup: Failed to open the .conf file: FilesRedis6390redis.windows-service.6390.conf CWD=D:Program FilesRedis6390 起初,从新创立集群节点目录(即:D:RedisCluster6380),运行命令就失常了。 其余节点反复运行命令即可,如下图: 运行实现后,关上Windows零碎服务查看,6个Redis节点服务曾经装置胜利。启动所有节点服务。 3 下载安装Ruby3.1 下载安装Ruby下载地址:https://rubyinstaller.org/downloads/ ...

March 30, 2021 · 1 min · jiezi

关于redis:从相识到相惜Redis与计算存储分离四部曲

摘要:协定兼容问题、性能问题、数据备份问题、数据容量问题……这些都是数据库在应用过程中必然会遇见的问题。就好比抉择结婚对象,你须要去比照不同的方面,最初选出最好的、最合适的。本文分享自华为云社区《【云驻共创】Redis与计算存储拆散四部曲:相识相惜,相辅相成》,原文作者:启明。 近期全国两会正在轰轰烈烈的召开,各人大代表也基于本人的一些实际提出了本人的意见,例如“出台手机设施适老规范”、“老师处分不与升学率挂钩”、“进步留学生招生规范”等等。这些问题必不可少地引来了网上用户的各种探讨声音,你甚至能够设想出网上用户深夜在致力敲键盘的样子…… 当然,咱们明天来不是来讲全国两会的。咱们技术人,技术魂,要讲的是这“网上探讨的声音”背地的技术——Redis。现如今咱们网上聊天曾经是粗茶淡饭了,那么你有没有意识到,在咱们聊天的背地,其实是有一个非常复杂的聊天零碎的呢?在这简单的聊天零碎中的音讯推送性能,更是其十分重要的一个模块。一般来说,音讯推送,是采纳Redis的历史数据结构来实现的。这个性能的简略使用,就是用户能够通过历史的程序查找,实现查看历史音讯的性能。 与Redis相遇置信到这里,大家对Redis的功能强大曾经有肯定认知了。那么咱们来正式介绍一下Redis:Redis(Remote Dictionary Server ),即近程字典服务,是一个开源的应用ANSI C语言编写、反对网络、可基于内存亦可长久化的日志型、Key-Value数据库,并提供多种语言的API。Redis自身有三个长处:快、稳、准,也就是时延低、性能好、数据结构丰盛。如此弱小的Redis,是“电商秒杀”等业务场景中的“熟客”:将秒杀商品的库存数量存入Redis,通过Redis来提供一个全局库存的实时扣减和查问服务。 然而,没有任何技术是完美无瑕的,Redis亦如此。Redis自身有几个毛病: Redis的bgsave影响性能;Redis的集群治理的一致性十分弱;Redis的内存限度了它的存储容量Redis的内存利用率只有一半;Redis没有冷热拆散机制。以上都是Redis的一些毛病,是不是看完感觉Redis又被“拉下神坛”,不如不必了?不要放弃,针对开源Redis的这些毛病,华为云数据库团队,做了“亿点”致力! 与GaussDB(for Redis)相识通过千难万险,含辛茹苦,千锤百炼,华为云自研出了一款全新的Redis数据库,也即是GaussDB ( for Redis )!!! 华为云的自研Redis源自于GaussDB,采纳了最先进的计算存储拆散架构和多模架构——属于业界独创。而GaussDB,则是华为云数据库的亮点品牌,是华为云引以为傲的数据库架构。 针对华为云的GaussDB,咱们来做一个简略的介绍吧(架构图如下):其是基于DFV架构来构建的。而DFV则是华为外部自研的超级DataLake(分布式存储池),可用于构建全栈数据服务架构,比方存储局部反对FusionStorage、云盘ECS、对象存储OBS,数据库局部反对的NoSQL、OLTP,大数据局部则反对HDFS的生态、Hadoop、Hbase、Hive等等。 通过下图能够看到,在下层的数据服务和上层的存储之间,是通过RDMA的高性能网络来连贯,从而可能起到一个升高时延的作用。作为最底下的存储层,被分成了不同的存储介质,如SCM、NVMe SSD、HDD、众核/多核等等。不同的存储介质是用来满足不同的服务对于性能的不同的需要的。 这里能够看出,其实GaussDB NoSQL就是一套成熟的DFV架构,也是集华为整个公司的力量去构建的一个架构最初孵化出的一个产品。其背地的心血、可用性,以及价值,都是难以估计的。 OK,咱们再来看看NoSQL的“全家福”(见下图)。能够看到,下图曾经囊括了NoSQL的全栈的数据库,包含Redis、Influx、Cassandra、Mongo在内,都是基于GaussDB雷同的架构去实现的。 拆解来看,这整套架构分为三个档次,从上往下别离是: 服务层(Service Layer),次要负责数据库的协定的解析、解决、执行以及回包等等;索引层(Index Layer),次要负责两头的路由及元数据管理等等;继续化存储层(Persistent Layer),也即是DFV POOL。 当然,咱们明天不会把每个局部都进行解说,而是要对其中的Redis进行更深刻的解说,其所领有的强统一、秒扩容、超可用、低成本这四个特点,让它成为了“家族中最靓的仔”。咱们来一步步深刻理解一下它吧。 与GaussDB (for Redis)相知在对Redis的四个个性进行深一步解说之前,咱们先对GaussDB ( for Redis )有一个全面的意识吧。从架构设计上(见下图): 设计了中心化的征询治理--ConfigureSever(cfgsvr):也就说用它来防止的就是社区Redis在集群治理上弱统一的一些问题;设计了proxy的接入形式:让一些非class的用户通过这个proxy接入;设计了Slot的数据管理:在最底层的ShardServer,设计Slot的数据管理。是说每一个我的项目Server会别离负责不同的Slot,每个Slot又对应不同的数据,最终的数据实际上都是落在最底层的分布式共享存储池(DFV POOL)上。 到这里,置信大家对GaussDB ( for Redis )的架构和性能曾经有了肯定的印象,那么咱们便来具体介绍它的硬实力吧! 硬实力一:强统一一提到“强统一”,很多业务开发人员会潜意识认为是一个比拟高(fu)级(za)的技术,然而对他/她本身的业务逻辑,甚至他/她本身代码能力的进步,其实没有任何帮忙。他们会说,“我不须要强统一啊”,或者,“强统一跟我没有关系”。 但咱们听听业界大牛对此的认识:强统一不仅仅是一个技术需要,实际上它也是一个业务需要。咱们如何去了解这句话呢?咱们来举个栗子:三八妇女节刚刚过来,在这个无论大大小小的节日,都要被蹭一波流量的时代,当然少不了电商们的促销流动。电商们在做促销流动的时候,整个平台的流量是十分大的,然而整个零碎可能抗住的压力又十分无限,这个矛盾要怎么解决呢?这里依赖的就是Redis的计数器,来构建的一个十分精美的限流机制。 硬件不够,软件来凑。这是当代电商在接受十分大的并发流量的时候的一个根本伎俩。那么Redis在这其中是如何发挥作用的呢?咱们来详细分析一下这个限流机制:在Redis里是有一个计数器的这么一个性能的。那么咱们在使用过程中,会应用其中一个key来做限流。咱们会首先对key做一个初始化的赋值,假如赋值1000。那么,当下层的业务调用API的时候,Redis的限流器就会做一个decrement的操作,即进行减1的一个操作。每次调用咱们都会减1,直至key的值变为0,调用会暂停。期待肯定的周期之后,零碎会从新初始化key,而实现电商在固定周期内限度调用次数的性能。 听着很美妙是不是?然而在这个过程中,却会有一些“意外”产生,其中主从不统一是外围问题。 电商节当天的流量压力之大,不须要咱们赘述。流量压力过大会引发的问题就是,”主”Redis的buffer会产生肯定的沉积,如果再加上”主”Redis遇上宕机,就会导致”主”从产生切换。鉴于Redis的”主”从是异步的,一旦主从产生切换,那么之前在“主”下面做的decrement的操作将无奈同步到“从”,最初导致“从”上的流控的数值比实在数值少了很多。然而切换过程,对于下层的调用接口来说,是没有感知的,它将持续尝试调用,即便理论曾经decrement至0,限流器仍然会通过它的申请,最初这些数据都会积淀到最底层、最单薄的MySQL数据库,最初导致整个零碎的“雪崩”。 这时候,就是咱们GaussDB ( for Redis )“强统一”性能出场的时候了。针对主从不统一的问题,GaussDB ( for Redis )在设计之初就是一个强统一的数据库,摒弃了开源社区的异步赋值机制。它被设计成在存储层(DFV层)去进行强统一的数据同步,而非在计算层。这样一来,在一开始便防止了任何两头态下的数据的不统一。妈妈再也不必放心咱们宕机导致数据失落啦~ 硬实力二:秒扩容咱们以在疫情期间十分炽热的在线教育为例。假如一个在线教育公司应用Redis作为存储介质。Key对应课程ID, Field对应用户ID。公司在设计之初可能没有思考到疫情会给他们带来爆发式的用户增长,导致哈希收缩,最初冲破Redis所在节点的内存限度。那么针对疫情,他们必须要进行扩容。 可是扩容并不是一个简略的事件,甚至能够说是一个高危的操作。因为Redis的扩容,是阻塞式的,以key by key的形式去进行迁徙,效率十分低下。扩容期间,key是不可拜访的,并且会继续到扩容完结。 阻塞工夫长是它的第一个问题。第二个问题更加重大。大家都晓得,Redis不仅有主从,还有HA(哨兵)。一旦阻塞工夫过长,你的主节点长期没有响应,HA就会断定你的主节点曾经挂掉,而后把主节点“杀掉”,切换主从关系,让“从”接管申请。留神,这里的切换是产生在扩容迁徙期间的,而一旦产生切换,就会导致扩容迁徙失败,即扩容失败,最初导致哈希的数据一部分散布在源节点,另一部分散布在指标节点。这种景象即便是人工染指也很难修改。 咱们来看看GaussDB ( for Redis )是怎么解决这个问题的。GaussDB ( for Redis ) 在设计的时候,借助了存算拆散这样一个架构,把CPU和IO资源进行分池,从而实现按需扩容。 这样的话,在迁徙的时候,就不须要把数据从一个节点拷贝到另一个节点,那么扩容过程就会变得更加轻量且平安。 ...

March 30, 2021 · 1 min · jiezi

关于redis:故障分析-Redis-内存碎片率太低该怎么办

作者:任仲禹爱可生 DBA 团队成员,善于故障剖析和性能优化,文章相干技术问题,欢送大家一起探讨。 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。 背景问题偶尔收到某客户问题“我的 Redis 内存碎片率很低在 0.2 左右,网上说会导致 Redis 性能变慢,我该咋办?”。 官网的计算 Redis 内存碎片率的公式如下: mem_fragmentation_ratio = used_memory_rss / used_memory即 Redis 向操作系统中申请的内存 与 分配器调配的内存总量 的比值,两者简略来讲: 前者是咱们通过 top 命令看到的 redis 过程 RES 内存占用总量后者由 Redis 内存分配器(如 jemalloc)调配,包含本身内存、缓冲区、数据对象等两者的比值后果 < 1 示意碎片率低, > 1 为高, 碎片率高的问题百度上海量文章有介绍,不多赘述,但碎片率低根本都归咎于应用了 SWAP 而导致 Redis 因拜访磁盘而性能变慢。但,真的是这样吗? 验证客户生产环境中 禁用了 SWAP数据量为 60M 左右repl-backlog-size 即复制积压缓冲区配置为 1G所以我这边设置下 vm.swappiness = 1 将 swap 先关掉,设置 repl-backlog-size=512M,再启个 Redis 空实例。 看下 memory stats,因为没任何键、复制线程、客户端,所以数据对象占用内存、复制积压缓冲区、客户端相干 buffer 都为 0;此时 Redis 内存分配器调配的内存总量是 863944(启动后初始内存量 startup.allocated+ 初始元数据 dataset.bytes),向操作系统申请的内存为 2789376,碎片率为 3.48。 ...

March 29, 2021 · 1 min · jiezi

关于redis:Redis的5种数据类型的命令上

明天先说string和list的命令,剩下的3种留作下一次水,呸,输入文章 先通知大家一个小常识,redis是有库的概念,0-13,每个库是独立的,默认应用0库,指定库进行数据管理应用 key:库号(0-13) string类型命令set key value [EX | PX | KEEPTTL] [NX | XX] [GET]NX 如果存在就不批改XX 不论存不存在间接批改EX seconds 设置键key的过期工夫,单位时秒PX milliseconds 设置键key的过期工夫,单位时毫秒KEEPTTL 获取 key 的过期工夫GET 返回 key 存储的值,如果 key 不存在返回空get key 获取指定key的value值mset key1 value1 key2 value2 ...... 插入多条数据mget key1 key2 ...... 取出多条数据append key value 在指定key的value值上进行追加value值GETRANGE key start(开始索引) end(完结索引) 截取指定索引的value值 SETRANGE key offset(开始索引) value 指定索引进行笼罩,超过长度主动裁减strlen key 获取指定key的value的长度object encoding key 查看制订key的value值所对应的实在编码INCR key 对制订key进行自增INCRBY key number 对指定key的value值与number相加(encoding类型为int)DECR key 对制订key进行自减DECRBY key number 对指定key的value值与number相减(encoding类型为int)INCRBYFLOAT key float 与float小数进行相加MSETNX key1 value1 key2 value2 ...... 多条插入或者批改,如果存在则批改失败,并且整体命令回滚SETBIT key offset(偏移量) value(只能是0或者1) 操作二进制命令GETBIT key offset(偏移量) 获取指定key下某偏移量的值(值为1或0)BITCOUNT: ...

March 29, 2021 · 1 min · jiezi

关于redis:Redisson-分布式锁实现原理

应用 加锁机制lock()底层是通过一段lua脚本实现的KEYS[1]代表你加锁的那个key,RLock lock = redisson.getLock("myLock");这里你本人设置了加锁的那个锁key就是“myLock”ARGV[1]代表的就是锁key的默认生存工夫,默认30秒ARGV[2]代表的是加锁的客户端的ID,相似于上面这样:8743c9c0-0795-4907-87fd-6c719a6b4586:1加锁流程:1.判断是否存在这个加锁的key2.如果不存在,通过hset命令加锁3.设置过期工夫 锁互斥机制如果客户端2来尝试加锁,执行了同样的一段lua脚本。1.第一个if判断这个key发现已存在,走第二个if判断key中的客户端的id是否与是客户端2的id2.如果发现不是,客户端2会获取到pttl myLock返回的一个数字,这个数字代表了myLock这个锁key的残余生存工夫。比方还剩15000毫秒的生存工夫。此时客户端2会进入一个while循环,不停的尝试加锁。实际上的原理:当锁正在被占用时,期待获取锁的过程并不是通过一个 while(true) 死循环去获取锁,而是利用了 Redis 的公布订阅机制,通过 await 办法阻塞期待锁的过程,无效的解决了有效的锁申请浪费资源的问题。 watch dog主动延期机制客户端1加锁的锁key默认生存工夫才30秒,如果超过了30秒,客户端1还想始终持有这把锁,怎么办呢?简略!只有客户端1一旦加锁胜利,就会启动一个watch dog看门狗,他是一个后盾线程,会每隔10秒检查一下,如果客户端1还持有锁key,过期工夫持续缩短为30s。 可重入加锁机制下面那段lua脚本。第一个if判断必定不成立,“exists myLock”会显示锁key曾经存在了。第二个if判断会成立,因为myLock的hash数据结构中蕴含的那个ID,就是客户端1的那个ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”,此时就会执行可重入加锁的逻辑,他会用:incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 1 ,通过这个命令,对客户端1的加锁次数,累加1,变为myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 2 锁开释机制如果执行lock.unlock(),就能够开释分布式锁,此时的业务逻辑也是非常简单的。其实说白了,就是每次都对myLock数据结构中的那个加锁次数减1。如果发现加锁次数是0了,阐明这个客户端曾经不再持有锁了,此时就会用:“del myLock”命令,从redis里删除这个key 此种计划Redis分布式锁的缺点计划最大的问题,就是如果你对某个redis master实例,写入了myLock这种锁key的value,此时会异步复制给对应的master slave实例。然而这个过程中一旦产生redis master宕机,主备切换,redis slave变为了redis master。接着就会导致,客户端2来尝试加锁的时候,在新的redis master上实现了加锁,而客户端1也认为本人胜利加了锁。此时就会导致多个客户端对一个分布式锁实现了加锁。这时零碎在业务语义上肯定会呈现问题,导致各种脏数据的产生。所以这个就是redis cluster,或者是redis master-slave架构的主从异步复制导致的redis分布式锁的最大缺点:在redis master实例宕机的时候,可能导致多个客户端同时实现加锁。 参考大佬:托付,面试请不要再问我Redis分布式锁的实现原理!

March 28, 2021 · 1 min · jiezi

关于redis:RedisUtil

1.增加Redis依赖包 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version></dependency>2.RedisUtil实现代码 import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;/** * description * created by A on 2021/3/26 */public class RedisUtil1 { public static JedisPool jedisPool=null; public static Jedis getJedis(){ if(jedisPool==null){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(100); //最大可用连接数 jedisPoolConfig.setBlockWhenExhausted(true); //连贯耗尽后是否期待 jedisPoolConfig.setMaxWaitMillis(2000); //等待时间 jedisPoolConfig.setMaxIdle(5); //最大闲置连接数 jedisPoolConfig.setMinIdle(5); //最小闲置连接数 jedisPoolConfig.setTestOnBorrow(true); //连贯的时候测试一下ping pong jedisPool=new JedisPool(jedisPoolConfig,"hadoop102",6379,1000) ; System.out.println("开拓连接池"); return jedisPool.getResource(); }else{ return jedisPool.getResource(); } }}

March 26, 2021 · 1 min · jiezi

关于redis:Redis-Key淘汰策略

1、在redis中,key过期形式分为定期解决和惰性解决, Redis配置项hz定义了serverCron工作的执行周期,默认为10,即CPU闲暇时每秒执行10次;每次过期key清理的工夫不超过CPU工夫的25%,即若hz=1,则一次清理工夫最大为250ms,若hz=10,则一次清理工夫最大为25ms;清理时顺次遍历所有的db;从db中随机取20个key,判断是否过期,若过期,则逐出;若有5个以上key过期,则反复步骤4,否则遍历下一个db;在清理过程中,若达到了25%CPU工夫,退出清理过程;

March 26, 2021 · 1 min · jiezi

关于java:程序员自我提升不得不知道的一些宝藏网址收藏起来吧

很多同学想要自我晋升却不得门而入,所以明天我就来总结一些程序员必备的网站,囊括开源我的项目、解决bug、技术分享、一线资源和自我晋升的网站,心愿能对宽广程序猿有所帮忙,连忙给我珍藏起来,下次刷不到了可别说我没揭示你。 咱们首先来看一下国内比拟风行的程序员社区: 1、CSDN:https://blog.csdn.net/fly1nor...老牌社区也挺好,就是广告和低质量内容多些,去年底平台整顿之后还是有些成果的。这个根本都是间接搜寻后果跳转,犯懒不想看英文时候的选项。毛病就是泥沙俱下,须要大家的甄别能力 2、segmentfault:https://segmentfault.com/u/fl...SegmentFault创建于2012年,是中文畛域较大的技术问答交换社区平台,在这里你能够检索,交换和分享任何技术编程相干的问题及常识。产品原型来自于国外程序员问答社区StackOverflow,但其产品状态通过一年多的倒退,曾经有问答、博客、流动等,它还是多个编程马拉松流动的组织方。 3、知乎:https://www.zhihu.com/people/...这个不必多说了吧,知乎是国内最大网络问答社区,连贯各行各业的用户。其中程序员始终占据着半壁江山,老码农们分享着彼此的常识、教训和见解,为中文互联网源源不断地提供多种多样的信息。 4、哔哩哔哩:https://space.bilibili.com/40...这个想必也无需赘言,B站前身是二次元文化的小众视频社区,起初发展壮大倒是学习版块倒是占据了不少的底盘,程序员便是其中佼佼者,你说这找谁说理去 6、牛客网:https://www.nowcoder.com/home各个公司的面试题和面经分享,找工作前认真刷一刷,肯定会有很大播种!拿到心仪的 offer! 7、掘金:https://juejin.cn/user/281518...当初国内优质的开发者交流学习社区,能够去看大佬们写的文章,也能够本人分享学习心的,与更多开发者交换。意识更多的小伙伴儿,晋升集体影响力。 8、博客园:https://www.cnblogs.com/博客园创建于2004年1月,是一个面向开发者的常识分享社区。自创立以来,博客园始终致力并专一于为开发者打造一个污浊的技术交换社区,推动并帮忙开发者通过互联网分享常识,从而让更多开发者从中受害。博客园的使命是帮忙开发者用代码扭转世界。很多晚期的高质量内容都在博客园。 9、程序员客栈:https://www.proginn.com/程序员客栈是当先的程序员自在工作平台,如果你是有教训有资质的开发者,都能够来下面注册成为开发者,业余的时候做点我的项目,赚点零花钱。当然,如果你想成为一名自在工作者,程序员客栈也是能够满足的。只有你有技术,不怕赚不到钱。很多程序员日常在这里逛一下,接一点我的项目做。很多公司也在这公布我的项目需要。 51CTO:https://blog.51cto.com/14994642残缺笼罩了博客交换、待业培训、退职晋升、认证考试,平台还是不错的,不过课程品质参差不齐,同样的须要本人认真甄别。 国内的就先总结到这里,咱们再来看看几个国外的: 1、 GitHub — 开发者最最最重要的网站:https://github.com这个不必多说了吧,代码托管网站,下面有很多资源,想要什么轮子,下来搜就好了。并且呢,下面有很多优良的程序员,你能够在这里交到很多好敌人喔。 2、Stack Overflow — 解决 bug 的社区:https://stackoverflow.com/开发过程中遇到什么 bug,下来搜一下,只有搜寻的形式对,百分之 99 的问题都能搜到答案。在这里可能与很多有教训的开发者交换,如果你是有教训的开发者,还能够来这儿帮忙他人解决问题,晋升集体影响力。 3、Medium:https://medium.com/Hacker News:https://news.ycombinator.com/...这两个都是国外优质文章网站,Medium 的整体构造非常简单,容易让用户沉下心来专一于浏览。下面有很多高质量的技术文章,有很多厉害的人在下面公布内容。 除了这些论坛,程序员还有一些必备网站: 0. Google:https://google.com这个不必多说了吧,查资料,有问题,Google 一下。当然,能拜访的人天然会用,拜访不了的人,能够用必应或者百度吧。 1. 算法学习 LintCode:https://www.lintcode.com/算法学习网站,下来每天刷两道算法题,走遍天下都不怕。 2. 算法学习 LeetCode:https://leetcode.com/也是算法题网站,同上。 3. 算法学习 LeetCode 中文站:https://leetcode-cn.com/这个是下面算法题网站的中文站点,英文不好的能够刷这个,英文好的举荐去刷英文网站的题目,还能晋升英语能力。 4. Web 开发练习题:https://www.freecodecamp.org/这是国外发动的一个 Web 开发学习的网站,从简略到深刻,一步一步带你学习 Web 开发。就像一本练习册,并且当你实现相应的内容后,会失去相应的资格认证。 5. 百度前端技术学院 — 前端开发我的项目库:http://ife.baidu.com学前端的看这里,百度官网推出的前端开发学习技术学院,题目从简略到艰难,如果你把外面的题都做会了,找个 BAT 的前端工作不成问题的。 其余学习网站: 0. 各种编程语言,编程工具,各种轮子的官方网站要记得,学习一门语言或者一个工具,最优质的学习网站就是他的官方网站,官网文档。 1. 菜鸟教程:http://www.runoob.com/菜鸟教程的 Slogan 为:学的不仅是技术,更是幻想! 记住:再牛逼的幻想也抵不住傻逼似的保持!网站包含了HTML、CSS、Javascript、PHP、C、Python等各种根底编程教程。 2. 中国大学MOOC网:https://www.icourse163.org/中国大学MOOC是由网易与高教社携手推出的在线教育平台,承接教育部国家精品凋谢课程工作,向公众提供中国出名高校的MOOC课程。在这里,每一个有志愿晋升本人的人都能够收费取得更优质的高等教育。 举荐给前端程序员的技术、论坛、资讯网站:https://medium.freecodecamp.com/https://css-tricks.com/http://css-weekly.com/https://www.html5rocks.com/en/https://mobilewebweekly.com/http://www.echojs.com/http://us5.campaign-archive1....https://www.smashingmagazine....https://www.sitepoint.com/http://javascriptweekly.com/http://frontendfocus.co/https://frontendfoc.us/http://reactjsnewsletter.com/...http://feeds.feedburner.com/h... 举荐给前后端程序员的技术、论坛、资讯网站:https://hashnode.com/http://us4.campaign-archive1....http://rubyweekly.com/https://golangweekly.com/https://dbweekly.com/https://risingstack.com/http://nodeweekly.com/https://webopsweekly.com/https://postgresweekly.com/http://nodeweekly.com 举荐给前安卓程序员的技术、论坛、资讯网站:http://androidweekly.net/http://us2.campaign-archive2.... ...

March 26, 2021 · 1 min · jiezi