SGwanmin

在学习C语言和数据结构,,, 日了,上学时候没感觉啥的,学的越多发现得调头翻大学教材了,啊,西八!

导航

Redis开发实战-avpt

Redis开发实战

1.前言

Redis在我的项目经验中使用的比较少且浅,只是用来减少数据库访问次数及压力,提升请求响应速度,单纯的当做缓存来用,所以实操的部门只有基本的CRUD和分布式锁,这基本也能适应大多数的项目,而类似天猫双十一的那种高并发,雪崩穿透啥的,没用过只是听过这个名词而已,文章中也不会介绍这些。

Redis-EFCore-logger Code 使用Demo 已上传至github:https://github.com/Seth-Song/EFCore_Redis_logger

2.Redis集成和基础使用

Redis是运行在Dockers上的分布式缓存服务器,缓存的数据不在内存中,所以他具有以下特点:

  1. 分布式系统之间共享内存
  2. 生命周期长
  3. 分担系统内存,减少系统负荷
  4. 可能互相冲突

Memory缓存就是传统意义的缓存,数据直接存在内存中,虽然存取数据更快,但是缺点也很多,比如:生命周期会随系统的终止而结束,各微服务之间不能共享,对系统负荷大等,简称MC,这就是个Dictionary:
知识点:Dictionary不是线程安全的,项目中所有线程都可以访问,所以不需要设置成Static,如果需要使用线程安全的Dictionary请使用时ConcurrentDictionary

目前市面上比较流行的是CSRedisCore和StackExchange.Redis这两种,他们之前的区别如下:

  • CSRedisCore (currently used) 国内实现的著名的第三方客户端,该组件基于连接池模式,默认配置会预热50个redis连接。功能更加灵活,针对Redis的模式做了比较好的封装。 该组件最新版本提供了基于RedisBloom的filter实现,例如Bloom Filter。但是没有正式release,作者没有做过测试且明确表示后续不会持续维护该project。因此如果需要使用filter等的新特性,第一、稳定性不能保证;第二、需要手动引入全部CSRedisCore的工程,且发现bug需要自行fix,维护成本高。

  • StackExchange.Redis Stackoverflow出品,老牌的高性能、通用的Redis.NET客户端,可以很方便地应用Redis全功能,支持Redis Cluster。通过ConnectMultiplexer连接服务器,通过IDatabase接口调用Client API进行操作。 老版本(1.x)据用户反馈,存在明显的connection timeout的问题。作者在2.0大版本进行了针对性优化,目前该问题的反馈已经很少了,可以提供稳定的Cache支持。

package包,同名引用一下就可以,我们使用的是后者。

 

基础的使用,就不说了,直接调用StackExchange.Redis中的方法即可,在Demo中也有体现。

 

1.redis数据结构

存储字符串
1.set key value:设定key持有指定的字符串value,如果该key存在则进行覆盖操作,总是返回OK
2.get key: 获取key的value。如果与该key关联的value不是String类型,redis将返回错误信息,
因为get命令只能用于获取String value;如果该key不存在,返回null。 3.getset key value:先获取该key的值,然后在设置该key的值。 4.incr key:将指定的key的value原子性的递增1. 如果该key不存在,其初始值为0,在incr之后其值为1。
如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息 5.decr key:将指定的key的value原子性的递减1.如果该key不存在,其初始值为0,在incr之后其值为-1。
如果value的值不能转成整型,如hello,该操作将执 行失败并返回相应的错误信息。 6.incrby key increment:将指定的key的value原子性增加increment,如果该key不存在,器初始值为0,
在incrby之后,该值为increment。如果该值不能转成 整型,如hello则失败并返回错误信息 7.decrby key decrement:将指定的key的value原子性减少decrement,如果该key不存在,器初始值为0,
在decrby之后,该值为decrement。如果该值不能 转成整型,如hello则失败并返回错误信息 8.append key value:如果该key存在,则在原有的value后追加该值;如果该key 不存在,则重新创建一个key/value

 

存储list类型
1.lpush key value1 value2...:在指定的key所关联的list的头部插入所有的values,如果该key不存在,该命令在插入的之前创建一个与该key关联的空链表,
之后再向该链表的头部插入数据。插入成功,返回元素的个数。 2.rpush key value1、value2…:在该list的尾部添加元素 3.lrange key start end:获取链表中从start到end的元素的值,start、end可为负数,若为-1则表示链表尾部的元素,-2则表示倒数第二个,依次类推… 4.lpushx key value:仅当参数中指定的key存在时(如果与key管理的list中没有值时,则该key是不存在的)在指定的key所关联的list的头部插入value。 5.rpushx key value:在该list的尾部添加元素 6.lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素 7.rpop key:从尾部弹出元素 8.rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部 9.llen key:返回指定的key关联的链表中的元素的数量。 10.lset key index value:设置链表中的index的脚标的元素值,0代表链表的头元素,-1代表链表的尾元素。

  

存储Set
添加或删除元素
1.sadd key values[value1、value2……]:向set中添加数据,如果该key的值有则不会重复添加
例如:sadd myset a b c
2.srem key members[member1、menber2…]:删除set中的指定成员
例如:srem myset 1 2 3
获得集合中的元素
1.smembers key :获取set中所有的成员
smembers myset
2.sismember key menber :判断参数中指定的成员是否在该set中,1表示存在,0表示不存在或者该key本身就不存在(无论集合中有多少元素都可以极速的返回结果)
集合的差集运算 A-B
sdiff key1 key2 … : 返回key1与key2中相差的成员,而且与key的顺序有关。即返回差集。
集合的交集运算
sinter key1 key2 key3… :返回交集
集合的并集运算
sunion key1 key2 key3… : 返回并集
扩展命令(了解)
scard key : 获取set中的成员数量
例子:scard myset
srandmember key : 随机返回set中的一个成员
sdiffstore destination key1 key2 …: 将key1 key2 相差的成员存储到destination中
sinterstore destination key[key…] : 将返回的交集存储在destination上
suninonstore destination key[key…] : 将返回的并集存储在destination上

  

存储hash
1.赋值
hset key field value : 为指定的key设定field/value对
hmset key field1 value1 field2 value2 field3 value3 为指定的key设定多个field/value对
2.取值
hget key field : 返回指定的key中的field的值
hmget key field1 field2 field3 : 获取key中的多个field值
hkeys key : 获取所有的key
hvals key :获取所有的value
hgetall key : 获取key中的所有field 中的所有field-value
3.删除
hdel key field[field…] : 可以删除一个或多个字段,返回是被删除的字段个数
del key : 删除整个list
4.增加数字
hincrby key field increment :设置key中field的值增加increment,如: age增加20
hincrby myhash age 5
自学命令:
hexists key field : 判断指定的key中的field是否存在
hlen key : 获取key所包含的field的数量
hkeys key :获得所有的key
hkeys myhash
hvals key :获得所有的value
hvals myhash

  

存储sortedset
1.添加元素
zadd key score member score2 member2…:将所有成员以及该成员的分数存放到sorted-set中。
如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数。(根据分数升序排列) 2.获得元素 zscore key member :返回指定成员的分数 zcard key :获得集合中的成员数量 3.删除元素 zrem key member[member…] :移除集合中指定的成员,可以指定多个成员 4.范围查询 zrange key strat end [withscores]:获取集合中角标为start-end的成员,[withscore]参数表明返回的成员包含其分数。 zremrangebyrank key start stop :按照排名范围删除元素 zremrangescore key min max :按照分数范围删除元素 扩展命令(了解) zrangebyscore key min max [withscore] [limit offset count] :返回分数在[min,max]的成员并按照分数从低到高排序。
[withscore]:显示分数;[limit offset count];offset,表明从脚标为offset的元素开始并返回count个成员 zincrby key increment member :设置指定成员的增加分数。返回值是修改后的分数 zcount key min max:获取分数在[min,max]之间的成员个数 zrank key member:返回成员在集合中的排名(从小到大) zrevrank key member :返回成员在集合中的排名(从大到小)

 

2.redis和数据库双写的一致性

两个东西,能保证的往往是最终一致性,强一致性不推荐,建议直接用DB。。。

 

3.redis并发竞争Key问题

这里有一个点,我们是做软件的不是纯写Demo的,所以要考虑实际的生产环境,在使用Redis时,基本上全是集群环境,当涉及到多个key时,无法保证所有的key都在同一个redis-server上,所以redis的事务机制不用!那么用啥?问得好!

分布式锁

解释一下这个概念,因为网上很多demo都是直接加在redis上的,注意理解,分布式锁更像一种思想,这个锁,放在哪里都行,只要保证的是,在需要的时候能拿到就可以,DB/redis/甚至不考虑生命周期也可以放到MC中,如果不知道分布式锁是什么,自查吧。
理解了这个思想,接下来遇水架桥即可。
比如
1.如果key的操作要求顺序?

加个时间戳,排序成串行。

2.自己锁被其他线程释放了?

加个生成锁加个线程ID吧或者name也行,能确定是自己的
3.线程进去不出来了,一直占用?

加个过期时间。

4.线程进去了,干的慢,不是卡死了!

加个延期,,,

遇到问题解决就可以了,分布式锁,更多的是思想!


关于配置redis在这里 :redis进阶

其实还可再挖的深一点,于是我拿起了我的大学教材,日了,,,C语言程序设计和数据结构!

 

posted on 2022-04-08 11:13  GwanMin  阅读(165)  评论(0)    收藏  举报