当前位置: 首页 > Linux

Linux安装Redis_1

时间:2023-04-06 02:20:00 Linux

缓存机制详解问题一:为什么用户直接操作数据库效率低?链接创建/销毁需要很多时间JDBC/数据库连接池问题2:为什么创建链接需要时间?使用TCP协议3次握手机制4第二波操作说明:缓存机制的本质是降低用户访问物理设备的频率,减少用户交互的时间,提高对数据的响应能力.一、缓存机制的要素1、应该使用什么类型的数据结构?采用K-V结构2.内存特性断电后如何防止擦除?对内存数据进行持久化操作(保存到磁盘)3、内存容量有限,如何只保存热点数据?LRU算法/LFU算法/TTL算法/随机算法4.由于与硬件交互性强,所以采用C语言开发。2.Redis介绍官网:https://redis.io/中文网址:http://www.redis.cn/Redis是一个开源的(BSD许可),一个可以使用的内存数据结构存储系统作为数据库(非关系数据库)、缓存和消息中间件。它支持多种类型的数据结构,例如字符串、哈希、列表、集合、带范围查询的排序集合、位图、hyperloglogs和地理空间(geospatial)索引半径查询。Redis内置了复制、LUA脚本(Luascripting)、LRU驱动事件(LRUeviction)、事务(transactions)和不同级别的磁盘持久化(persistence),并通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(highavailability)。数据:读取:112000次/s写入:86000次/s平均100000次/s3.安装redis1)上传安装包安装包版本5.0.4(centos7目前不兼容redis6.x.x)2)解压安装打包并重命名tar-zxvfredis-5.0.4.tar.gzmvredis-5.0.4redis3)跳转到redis根目录(cdredis)执行makemakeinstall命令(一)make执行效果(二)make安装效果4)说明:redis的启动依赖于核心配置文件redis.conf。修改redis配置文件:(注释部分的wxz是我的缩写,请忽略!!!)(1)关闭IP绑定注释(2)保护模式(3)开启后台启动4.Redis进入命令1.启动命令:redis-serverredis.conf2.进入客户端:redis-cli-p63793.关闭redis:redis-cli-p6379shutdown5.字符串类型命令说明casesetaddkey-valuesetusernameadminget根据key获取数据getusernamestrlengetvaluelength根据keystrlenkeyexists判断key是否存在existsnamereturn1exists0不存在deldeletekeydelinrediskeyKeys用于查询是否满足条件keykeysstar查询redis中所有的keys,keysn?me使用占位符获取数据,keysnam*获取nam开头的数据msetassignmultiplekeys-valuemsetkey1value1key2value2key3value3mget获取多个key的值mgetkey1key2appendappendkey的valueappendkeyvaluetypechecks键的类型keyselect切换redisdatabaseselect0-15redis有16个数据库flushdb清除单个数据库flushdbflushall清除所有数据库flushallincr自动加1incrkeydecr自动减1decrkeyincrby指定值加incrbykey10decrby指定值减decrbykey10expire指定key的有效时间,单位秒expirekey20keyexpiresafter20secondspexpire指定key的失效时间,单位millisecondspexpirekey2000keyexpiresafter2000毫秒ttl检查key的剩余生存时间ttlkey-2datadoesnotexist-1thedataNevertimeoutpersistrevocationkeyexpirationtimepersistkey6.Redis介绍1)导入jar包redis.clientsjedisorg.springframework.dataspring-data-redis2)编辑测试用例setnx如果数据存在,什么都不做,如果数据不存在,赋值setex在设置超时时间时必须保证操作的原子性。要么同时成功,要么同时失败//如果数据存在,什么都不做,如果数据不存在,赋值@Testpublicvoidtest02(){Jedisjedis=newJedis("192.168.126.129",6379);jedis.flushAll();//jedis.set("redis","AAA");jedis.setnx("redis","BBB");System.out.println(jedis.get("redis"));}//添加一条数据,设置超时时间为10秒//设置超时时间需要注意//原子性:要么同时成功,要么同时失败。@Testpublicvoidtest03()throwsInterruptedException{Jedisjedis=newJedis("192.168.126.129",6379);//jedis.set("a","设置超时");//jedis.expire("a",10);jedis.setex("a",10,"设置超时");线程.睡眠(2000);System.out.println("剩余时间"+jedis.ttl("a"));}/***1.如果数据存在则不允许修改,否则允许修改*2.同时为数据设置超时时间。10秒*3.以上操作需要满足原子性要求*XX:存在才可以操作*NX:不存在只能操作*PX:毫秒*EX:秒*/@Testpublicvoidtest04(){Jedisjedis=newJedis("192.168.126.129",6379);SetParamssetParams=newSetParams();setParams.nx().ex(10);jedis.set("b","xxxx",setParams);System.out.println(jedis.get("b"));}7.hash类型命令说明:Hash类型可以用来保存对象和属性值。应用场景:一般工作中存储的数据都是基于一个业务对象。示例:用户对象{id:2,姓名:小明,年龄:19}命令说明casehsetis向对象添加数据hsetkeyfieldvaluehget获取对象的属性值hgetkeyfieldhexists判断属性是否存在对象存在HEXISTSkeyfield1表示存在0表示不存在hdeldeletehash中的属性hdeluserfield[field...]hgetall获取hash中的所有元素和值HGETALLkeyhkyes获取hash中的所有字段HKEYSkeyhlen获取散列中所有属性的个数hlenkeyhmget获取散列中指定字段的值hmgetkeyfield[field...]hmset为散列中多个字段设置值hmsetkeyfieldvalue[fieldvalue...]hsetnx设置hash的一个字段,仅当该字段不存在时有效HSETNXkey字段值hstrlen获取hash中指定key的值的长度HSTRLENkeyfieldhvals获取hash的所有值HVALS用户示例:一下单,包括用户信息,订单信息,物流信息...hsetorderIduser"用户信息"hsetorderIdorder"订单信息"hsetorderIdshipping"物流信息"八、list类型命令说明:Redis中的List集合是双端循环链表,可以分别从左右方向插入数据。List集合既可以作为队列使用,也可以作为栈使用队列:存储数据的方向与获取数据的方向相反。Stack:存储数据和获取数据的方向方向同命令说明Caselpush从队列左侧入队一个或多个元素LPUSHkeyvalue[value...]rpush从队列左侧入队一个或多个元素RPUS队列的右侧Hkeyvalue[value...]lpop从队列左端取出一个元素LPOPkeyrpop从队列右端取出一个元素RPOPkeylpushx当队列存在时从队列左侧取出一个元素LPUSHXkeyvaluerpushx当队列存在时从队列右侧入队一个元素RPUSHxkeyvaluelrange从列表中获取指定的返回元素LRANGEkeystartstopLrangekey0-1获取队列的所有数据lrem从队列中移除之前出现的countlist存储在key中具有value的元素count参数通过以下方式影响此操作:?count>0:从头到尾移除值为value的元素。?count<0:从末尾到开头删除值为value的元素。?count=0:删除所有值为value的元素。LREMlist-2"hello"将从list中存储的列表中删除最后两次出现的"hello"。需要注意的是,如果列表中不存在key,会被当成一个空列表,所以当key不存在时,该命令会返回0。lset设置索引位置的列表元素的值tovalueLSETkeyindexvalue关于秒杀业务Redis没有线程并发安全问题:单进程,单线程问题悲观锁:同步代码块乐观锁:数据库控制(加版本号,购买成功,版本号加1)如果update执行result为0,表示数据库没有更新,也就是商品没有被抢到。悲观锁和乐观锁都不好,都会增加数据库的压力。所以可以使用redis来实现秒杀。九、redis事务命令Redis有事务控制。但是事务控制是通过队列的方式来实现的。说明:redis中的操作可以添加事务支持。一个任务可以由多个redis命令完成。如果一个命令失败导致存储失败,需要实现事务回滚。命令说明casemultimarkatransactiontostart127.0.0.1:6379>MULTIOKexec执行multi之后发出的所有命令127.0.0.1:6379>EXECOKdiscard丢弃multi之后发出的所有命令注意如果redis服务器宕机/或者断电切断,整个内存数据可能会丢失。为了防止这种现象,redis内部引入了持久化机制。持久化:将内存中的数据按照一定的规则保存到磁盘中。2.RDB模式2.1RDB模式说明1)RDB模式是Redis默认的持久化机制。2)RDB方式记录内存数据的快照,持久化效率更高。(只保留当前最新的数据)3)RDB模式是周期性持久化,也可以手动操作。save(同步)用户操作可能会阻塞/bgsave后端操作(异步),登录redis客户端后执行这两个命令(redis-cli)4)。由于是定期备份,可能会导致数据丢失。2.2.2RDB模式配置项(dump.rdb)Redis重启会通过加载dump.rdb文件恢复数据。1).持久化策略save9001900seconds1update,thenpersistoncesave30010300seconds10updatesthenpersistoncesave601000060seconds10000updatethenpersistoncesave11效率极低。这样配置压测后不要做适当的调整。2).持久文件名3).持久化文件位置2.3AOF模式2.3.1AOF模式说明(appendonly.aof)1).默认情况下,AOF模式是关闭的,如果需要开启,手动配置(appendonlyyes)2)。AOF方式记录用户的操作过程,可以实现实时持久化操作,持久化文件比较大,维护难度大。3).如果同时开启了RDB和AOF模式,则默认以AOF模式为准。但是用户可以手动执行save命令,此时会生成一个rdb文件。4).AOF模式是异步操作,不会影响程序的正常使用。2.3.2AOF模式配置1).开启AOF配置2)。日志信息显示3).AOF模式持久化策略appendfsyncalways用户执行一步操作,持久化一次appendfsynceverysec每秒持久化一次性能略低于RDB模式appendfsyncno不主动持久化2.3.3如何选择持久化方式1.如果数据量小允许丢失,首选RDB模式更快2.如果不允许丢失数据,首选AOF模式。3、一般情况下host如何选择RDB模式,slave如何选择AOF模式。2.3.4关于坚持的面试题公司新来了一个很漂亮的实习生。在生产环境中,我弄错了Flushall命令,作为主管的你是如何处理的?解决方案:前提:持久化策略是带AOF的,如果是RDB的话是无法补救的。1、进入AOF文件,修改文件信息,删除flushAll命令。2.重启redis。2.4Redis内存策略2.4.1需求将Redis中的数据引入内存中。但是,内存资源相对较小。如何保证里面的数据是热点数据呢?2.4.2内存优化——LRU算法LRU是LeastRecentlyUsed的缩写,即最近最少使用,是一种常用的数据置换算法,它选择最长时间未被使用的数据进行淘汰。该算法为每个数据赋予一个访问字段,用于记录自上次访问数据以来经过的时间t。当一个数据需要淘汰时,选择t值最大的现有数据,即最近最少使用的数据淘汰。维度:时间T2.4.3内存优化-LFU算法LFU(leastfrequentlyused(LFU)page-replacementalgorithm)。即最不常用页面替换算法要求在页面替换时替换引用计数最小的页面,因为经常使用的页面应该有更大的引用计数。但是有些页面一开始用的很多,后面就不会用了。这样的页面会在内存中保留很长时间,因此可以将引用计数寄存器每隔一段时间右移一位,形成一个按指数衰减的平均使用次数。维度:使用次数2.4.4内存优化-随机算法2.4.5内存优化-TTL算法根据剩余生存时间,按时间少的排序,删除数据。2.4.6修改内存优化策略volatile-lru在设置超时数据中使用LRU算法allkeys-lru,所有数据使用LRU算法volatile-lfu,计算数据使用LFU机制有超时时间。allkeys-lfu是在所有数据中使用LFU算法volatile-random计算的。随机allkeys-random所有数据的随机算法volatile-ttl在设置了超时的数据中,TTL算法noeviction默认规则如果内存已满,则不进行任何操作,直接返回错误。2.4.7设置内存优化策略十一、Redis分片机制1分片机制说明:由于电商网站的数据量普遍较大,如果只使用单个redis节点进行数据存储,是无法完成任务的。因此,需要准备多个Redis公共实现内存数据扩展。2准备3台redis2.1编辑配置文件1).准备文件目录2).修改端口号2.2启动多个redis命令:redis-server6379.confredis-server6380.confredis-server6381.confRedis分片案例测试(操作ShardedJedis对象,JedisShardInfo)3ConsistentHash算法3.1算法介绍Consistenthash算法由MIT提出1997年,它是一种特殊的哈希算法,目的是解决分布式缓存问题。[1]删除或添加服务器时,尽量少改变已有的服务请求和处理请求服务器的映射关系。一致性哈希解决了分布式哈希表(DistributedHashTable,DHT)中简单哈希算法的动态伸缩问题[2]。3.2原理常识:1.普通散列函数8位十六进制数。(2^4)8=2^32可能2.如果对相同的数据进行散列,则值必须相同。3.如果值相同,数据不一定是相同的哈希冲突。3.3特征——平衡(Balance)①平衡是指哈希结果要均匀分布到各个节点,从算法[4]上解决了负载均衡问题。说明:通过虚拟节点实现数据均衡。3.4特点——单调性②单调性是指在增加或删除节点时,不会影响系统的正常运行[4]。特点:如果进行数据迁移,尽量保持原有数据不变。3.3.5特点——去中心化③去中心化是指数据应该存储在分布式集群中的各个节点中(节点本身可以??有备份),不需要每个节点都存储所有的数据[4]。解释:不要把鸡蛋放在一个篮子里。12、Redis哨兵机制(一主二从)1.1分片机制的问题如果其中一种redis分片机制出现故障,整个Redis分片将无法正常使用。分片机制没有高可用效果。1.2哨兵机制说明1.2.1配置哨兵的前提条件:实现redis数据同步(主从数据同步)是实现哨兵配置的前提条件。1.2.2复制文件1.2。3删除多余的持久化文件删除完成后,一一启动redis。如图1.2.4所示,实现了主从挂载。Host:6379Slave:6380/6381Command:检查nodeinforeplication2的状态。主从挂载命令master-slaveCheck1.3Sentinel工作原理步骤:1)。Sentinel启动时会动态监控主机,然后使用PING-PONG心跳检测机制检查主机是否正常。2).Sentinel连接到主机后,会获取到相关的主从服务信息。方便以后的选举。3).当哨兵发现主机宕机时,它会使用随机算法选择一个新的主机。之后,其他节点将成为新的宿主。从1.4哨兵配置1.4.1复制文件1.4.2修改哨兵配置文件1)。关闭保护模式!2).开启后台操作3).监控主机目前只有一个哨兵,所以1票才会生效。哨兵设置为奇数。选)1.4.3Sentinel高可用测试前提:由于之前已经搭建好redismaster和slave,三个redis都处于启动状态。1).启动哨兵命令:redis-sentinelsentinel.conf2)。sentinel高可用测试第一步:查看redis主机状态。第二步:关闭redis主机。第三步:等待10秒,查看slave是否切换为Host。此时配置文件(sentinel.conf)会自动改变(随机选择):第四步:重启主机,查看是否为新主机。从1.4.4Sentinel入口case/***实现redissentinel测试*mymaster配置文件(sentinel.conf)写在mymaster中*Sentinel只连接master,不连接slave*/@TestpublicvoidtestSentinel(){//1。链接哨兵集Setsentinels=newHashSet<>();sentinels.add("192.168.126.129:26379");JedisSentinelPoolpool=newJedisSentinelPool("mymaster",sentinels);绝地武士jedis=pool.getResource();jedis.set("aaa","aaaaaaa");System.out.println(jedis.get("aaa"));spring整合:1.把pool交给Spring管理。@BeanpublicJedisSentinelPooljedisSentinelPool(){//1.设置连接池大小JedisPoolConfigpoolConfig=newJedisPoolConfig();poolConfig.setMinIdle(5);//设置最小空闲数poolConfig.setMaxIdle(10);//Set设置最大空闲数poolConfig.setMaxTotal(100);//最大连接数//2。链接哨兵集合Setsentinels=newHashSet<>();sentinels.add(哨兵);返回新的JedisSentinelPool("mymaster",sentinels,poolConfig);}2。注入这个池对象并获取资源@AutoWiredprivateJedisSentinelPoolsentinelPool;//从池中动态获取数据Jedisjedis=sentinelPool.getResource();jedis.close();//使用完成后,关闭(返回)链接;分片哨兵总结1.分片主要实现内存扩展,没有高可用的作用。2、Sentinel主要实现高可用效果,没有实现内存数据的扩展。Sentinel本身没有高Available效果。如何优化:内存扩展,节点的高可用redis集群实现。十三、Redis集群搭建:集群搭建