狐表集成Redis教程,三行代码搞定!使用CsRedis高分Git库,redis官方推荐的第三方库,简单易用!顺便分享Redis服务器安装和科普【缓存穿透、缓存击穿、缓存雪崩】

发表日期: 2021-05-29

前言:Redis是什么?
如果你不知道,那你不用看这个帖子,没用的,你没产生需求,浪费时间的。
Redis大概就是一个把狐表里的字典功能,独立出来。狐表用全局变量创建一个字典,跟redis也差不多效果,只不过redis的读写性能超强,还有断电支持自动把字典存到硬盘,下次启动继续用,而狐表退出后字典就没了。

举个例子:
假如公司有3000人,做了个邮件小系统,我群发了一封文本邮件。
这时候大家都去打开看邮件,瞬间有3000并发打下去数据库,想访问某个邮件ID对应的文本内容,那数据库肯定很难受,于是有3级缓存方法:
1.把内容直接写成html文件,客户访问,立刻返回文件,消耗磁盘IO来抵御并发,并发上限由磁盘IO决定+网速
2.把内容直接写进狐表某个全局字典,客户访问,立刻从内存的字典里返回,内存的并发基本无敌,所以并发上限由网速决定。
       但是狐表的能用的内存只有1.5G,而且字典并不会自动过期清理缓存,日积月累迟早会令狐表崩溃,整套系统停机。
3.把内容直接写进Redis这种纯内存型数据库,客户访问,立刻从内存返回,内存的并发基本无敌,所以并发上限由网速决定。
       Redis能用的内存取决于你机器有多大,无上限,并且可以设置过期时间,自动清理

百度百科描述Redis:

按此在新窗口浏览图片

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1] 
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
Redis的官网地址,非常好记,是redis.io。(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地),Vmware在资助着redis项目的开发和维护。


一、Redis的服务器安装教程
1服务器安装
1.1安装教程
按照这个教程一步步来,绝对没问题
https://blog.csdn.net/qq_35885175/article/details/114318964

安装包下载: Redis-x64-3.2.100.zip,网上随便搜的http://www.edowning.net/soft/143829.htm

1.2注意的权限不足的坑
英文:redis.exceptions.ResponseError: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
中文翻译:MISCONF Redis配置为保存RDB快照,但当前无法持久保存在磁盘上。 禁用了可能修改数据集的命令,因为此实例配置为在RDB快照失败时在写入过程中报告错误(stop-writes-on-bgsave-error选项)。 请检查Redis日志以获取有关RDB错误的详细信息。

错误原因:redis过了一段时间,会把内存的数据持久化存本地,这需要有足够的权限。如果权限不足,就会无法写入,导致以上的报错

解决方法:

按此在新窗口浏览图片


2测试客户端
推荐Redis Client
下载地址:http://www.itmop.com/downinfo/15197.html
解压就能使用

此主题相关图片如下:2.png
按此在新窗口浏览图片


二、狐表使用CsRedis的教程

1.简介
1.1下载dll
适用于net4.0的dll下载:

以下内容只有回复后才可以浏览
这玩意面向高阶用户,得打个广告!在我的淘宝宝贝描述最下方有 狐表集成Redis的dll下载

https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-908885936.2.e92b57145xpdhp&id=566002255758


官方文档:https://github.com/2881099/csredis
第三方使用教程:https://www.cnblogs.com/yaopengfei/p/14211883.html

这个库最大的亮点,就是方法名与redis官方完全一样!在教程里没写到的方法名称,一律可以在这里查看https://www.redis.net.cn/order/ 

此主题相关图片如下:3.png
按此在新窗口浏览图片


1.2添加引用

此主题相关图片如下:4.png
按此在新窗口浏览图片
1.3安装.net4.7.2
这个dll需要用到.net4.7.2的一些接口,所以需要电脑装好.net4.7.2或以上的版本,自行百度安装。
如果没安装好,使用过程可能会出现以下错误:

此主题相关图片如下:3.png
按此在新窗口浏览图片

1.4更新代码精灵
用我提供的help.mdb覆盖到你的狐表,例如C:\foxtable\Professional,因为我为代码精灵增加了很多关于这个爬虫工具的方法和属性
代码精灵的用法,更多可以参考我之前的帖子:
[免费开源]狐表代码精灵管理器,自己改造狐表的官方代码编辑器,增加提示,自定义事件、方法、对象,非常简单,只需要2步!不用依赖任何第三方工具,永久跟着官方升级  
https://ey.mbldt.com/ExpShare/113.html

按此在新窗口浏览图片

2.初始化
2.1基本使用
RedisHelper.Initialization(New CSRedis.CSRedisClient("127.0.0.1:6379,defaultDatabase=0"))
1. RedisHelper是全局静态方法,把实例初始化进去后,就能一直使用,任意地方都能直接用
2. 通俗点说RedisHelper就类似一个女秘书,你把连接redis的钥匙给她,以后你想Set或者Get,都直接可以委托她干活,不再需要自己重复新建实例和初始化
3. 她还会自动连接数据库和根据情况自行断开,非常舒心
备注:如果连接失败报错,基本都是你的Redis没配置好,你用第三方客户端连接试试,顺便可以把报错的中文内容,也去百度下

2.2连接字符串说明

关键词默认值作用
name用户名,一般都不用管
password连接密码
defaultDatabase0默认连接的db数据库
connectTimeout5000连接超时,毫秒
syncTimeout5000读写超时,毫秒
autoDisposetrue闲置时自动断开
sslfalse是否ssl加密
prefixkey前辍,所有方法都会附带此前辍

3.通用方法

此主题相关图片如下:5.png
按此在新窗口浏览图片


3.1获取所有键名的数组
Dim keyAry As String() = RedisHelper.Keys("*") 
For Each k As String In keyAry
    Output.Show(k)
Next
'结果abc
3.2获取元素的过期时间
RedisHelper.Set("d", "ddd",100)
Dim ttl As Integer = RedisHelper.Ttl("d")
Output.Show(ttl)
'结果100,就是100秒后过期
3.3判断key是否存在
Dim bo As Boolean = RedisHelper.Exists("b")
Output.Show(bo)
'结果true
3.4删除key
output.show(RedisHelper.Del("a"))
output.show(RedisHelper.Del({"a","d"}))
'返回成功删除的元素的个数
3.5设置key过期秒数
Dim bo As Boolean = RedisHelper.Expire("a", 60) '60秒
Output.Show(bo)
'设置成功就返回true,否则false,不会报错
4.String类型Key
4.1写入/覆盖
RedisHelper.Set("d","ddd") '不过期
RedisHelper.Set("d","ddd",100) '100秒过期
  1. 同步和异步都能写入
  2. 写入成功会返回True
  3. 所有key/value都`区分大小写`
  4. 注意布尔值会转成0/1存入redis,读取也是0/1

4.2读取
output.show(RedisHelper.Get("d"))
  1. 同步和异步都能读取
  2. 不存在会得到空字符串,可通过<>""来判断

4.3整数自增器
  1. 创建一个整数值的自增器,调用一次`默认+1`,也可以指定增加值
  2. 这个自增`可以用在异步`,我测试过1w次异步自增,最终结果是10000
  3. 会返回当前的自增器数值
Output.Show(RedisHelper.IncrBy("ct")) '结果是1
Output.Show(RedisHelper.IncrBy("ct"))  '结果是2
Output.Show(RedisHelper.IncrBy("ct",3)) '结果是5
5.Hash类型Key(即无序字典)
5.1写入/覆盖
RedisHelper.HSet("myhash", "userName", "ypf")
RedisHelper.HSet("myhash", "userAge", 20)
RedisHelper.HIncrBy("myhash", "count", 1)
按此在新窗口浏览图片

5.2整数自增器
  1. 创建一个整数值的自增器,调用一次`默认+1`,也可以指定增加值
  2. 这个自增`可以用在异步`,我测试过1w次异步自增,最终结果是10000
  3. 会返回当前的自增器数值
RedisHelper.HIncrBy("myhash", "count", 1)
5.3读取所有值
Dim zd As Dictionary(of String ,String) = RedisHelper.HGetAll("myhash")
For Each key As String In zd.Keys
    Output.Show(key & ":" & zd(key))
Next
结果:
userName:ypf
userAge:20
count:3

5.4读取指定值
Output.Show(RedisHelper.HGet(Of String)("myhash","userName"))
Output.Show(RedisHelper.HGet(Of Integer)("myhash","userAge"))
当读取不存在的字典或key时,会返回空字符串,不会报错

5.5删除某个值
Output.Show(RedisHelper.HDel("myhash","count"))
Output.Show(RedisHelper.HDel("myhash",{"count","userAge"})
'返回成功删除的元素个数


6.List类型Key(即有序数组)
6.1右侧顺序增加
增加后会返回当前数组的总长度
RedisHelper.RPush("myList", "001")
RedisHelper.RPush("myList", "002")
RedisHelper.RPush("myList", "003")
按此在新窗口浏览图片

6.2左侧头部插入
RedisHelper.LPush("myList", "004")
RedisHelper.LPush("myList", "005")
RedisHelper.LPush("myList", "006")
按此在新窗口浏览图片

6.3右侧尾部删除并返回该元素
Output.Show(RedisHelper.RPop("myList"))
按此在新窗口浏览图片

6.4左侧头部删除并返回该元素
Output.Show(RedisHelper.LPop("myList"))
按此在新窗口浏览图片

6.5获取指定范围的元素
'1获取从左边开始的前3个元素。假如一共就2个元素,也不会报错
Dim l1 As String() = RedisHelper.LRange("myList", 0, 2)

'2获取从左边开始,获取所有的元素
Dim l2 As String() = RedisHelper.LRange("myList", 0, -1)
右侧同理:
RedisHelper.RRange("myList", 0, -1)
7.Set类型Key(即无序集合)
7.1增加
由于是无序的,所以重复添加是无效,例如重复添加a,实际最后只有1个a
添加后返回成功添加的元素个数
RedisHelper.SAdd("school", "a")
RedisHelper.SAdd("school", "b")
RedisHelper.SAdd("school", "c")
RedisHelper.SAdd("school", "d")
RedisHelper.SAdd("school", "e")
按此在新窗口浏览图片

7.2判断元素是否存在
Output.Show( RedisHelper.SIsMember("school", "b"))

'结果true


7.3移动指定元素
Output.Show(RedisHelper.SMove("school","school2","a"))
'1把a元素从school移动到school2,成功就返回true
'2如果school2不存在,就自动创建

7.4删除指定元素
Output.Show(RedisHelper.SRem("school","a")) 
Output.Show(RedisHelper.SRem("school",{"a","c"}))
'返回成功删除的元素数量


7.5随机获取一个元素
Output.Show(RedisHelper.SRandMember("school"))
7.6获取集合
Dim l1 As String() = RedisHelper.SMembers("school")
For Each s As String In l1
    Output.Show(s)
Next
'结果是无序的输出

三、Redis进阶:缓存穿透、缓存击穿、缓存雪崩的区别和解决方案

1.缓存带来的问题

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

但是既然是缓存,就得定时清理,不然会挤爆我们的内存,所以便有了有过期设置,这个过期功能却又带来一些问题...下面开始讲解


按此在新窗口浏览图片

2.缓存穿透

描述:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击


3.缓存击穿

描述:缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案:

  1. 设置热点数据永远不过期。
  2. 加互斥锁,互斥锁参考代码如下:

此主题相关图片如下:2.png
按此在新窗口浏览图片

代码说明(别看语法,看注释里的思路):


  1. 缓存中有数据,直接走上述代码13行后就返回结果了
  2. 缓存中没有数据,第1个进入的线程,获取锁并从数据库去取数据,没释放锁之前,其他并行进入的线程会等待100ms,再重新去缓存取数据。这样就防止都去数据库重复取数据,重复往缓存中更新数据情况出现。
  3. 当然这是简化处理,理论上如果能根据key值加锁就更好了,就是线程A从数据库取key1的数据并不妨碍线程B取key2的数据,上面代码明显做不到这点。


4.缓存雪崩

描述:缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,        缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
  3. 设置热点数据永远不过期。



随便看看
商务联系QQ : 2385350359

Copyright 2016-2023 江门蓬江区华越科技公司 版权所有 | 承接软件定制开发,欢迎联系
粤ICP备19148806号-5