目录介绍:
Docker 安装 Redis、MySQL、Gogs
人生有涯,学海无涯
最近接到一个项目,由于项目的独特性需要自己搭建一些环境,刚好之前学了一些 Docker(这里如果大家不熟悉 Docker 可以查看公号前面松哥写的 Docker 的系列文章),所以就决定采用 Docker 搭建,毕竟搭建方便、简单、快速。
大家在公网服务器安装 Redis 的时候 一定要设置密码,一定要设置密码,一定要设置密码 。
如果不设置密码很容易被黑客利用 Redis 的漏洞进行比特币的勒索。如果不巧遇到了那都是血的教训!切记不要抱有侥幸心理,或者简单的以为换个端口就可以了,端口的数量是有限制了,黑客完全可以遍历一下就破解了。最好两个都设置,既改端口也加密码,双保险,当然密码也不要简单到随便一个字典库就能破解的那种,尽量复杂点。
与 Redis 安装方式类似,不过这里获取的是指定版本的 MySQL 。
首先提到代码管理平台,大家首先想到的肯定是 Github 以及 Gitlab,这两种大家平时应该用到的比较多,开源软件用的大部分是 Github,公司内部大部分使用的是 Gitlab。Gogs 也是一种代码管理平台,相比 Gitlab 来说相对轻量级。
我这里为什么要使用 Gogs 而不使用 Gitlab 呢? 主要是个人服务器配置跟不上啊!!!
尝试了安装 Gitlab,安装后服务器完全跑不起来了,本来个人服务器性能就不是很好,上面还跑了几个程序,安装完 Gitlab 后连博客网站都打不开,果断放弃。官方推荐的安装 Gitlab 硬件配置是 4 核 8G,相对来说 Gogs 就轻量很多,安装后基本对服务器没什么影响,而且 Docker 安装十分方便。
注意修改端口号:
如果在上一步点击安装后一切正常那边跳过这一步,如果出现 MySQL error: The maximum column size is 767 bytes,那么很高兴你遇到一个坑,不过别怕,我们可以解决它只需要对 mysql 进行参数的设置就好了。
解决方案:
又一数据库高危漏洞爆出,数据安全如何有效保障?
2021年7月22日,Redis官方和开源Redis社区先后发布公告,披露了CVE-2021-32761 Redis(32位)远程代码执行漏洞。在32位Redis中,攻击者在Redis存在未授权访问的情况下可利用*BIT*命令与proto-max-bulk-len配置参数可能造成整形溢出,最终导致远程代码执行,本次漏洞等级为高危级别。需要说明的是,本次开源Redis的安全漏洞并不影响现网华为云GaussDB(for Redis)的任何实例,已经在使用华为云GaussDB(for Redis)的用户请继续放心使用。
通过本次漏洞可以发现,开源Redis对BITFIELD等命令的代码实现上存在问题,导致了对string数据类型的操作存在安全隐患。随时可能被恶意触发整形溢出BUG,甚至还会被恶意执行远程代码。因此,给了黑客可乘之机。本次漏洞的代码修复已经发布,官方建议用户尽快升级到开源Redis6.2.5, 6.0.15, 5.0.13这三个安全版本。
那么,对于此类数据库安全漏洞该如何防患于未然呢?
数据库漏洞属于软件漏洞中的一种,主要是被用来突破系统的安全策略。数据库漏洞往往会影响很大一个范围,除了影响数据库自身,还包括数据库所在操作系统和数据库所在局域网的整体安全。通常来说,防范和补救措施有:1. 紧跟官方通知,排查并升级数据库到安全版本。本次漏洞事件中,开源Redis用户应第一时间完成升级;2. 若短时无法升级,则从服务端开启访问限制,禁用危险命令;3. 通过白名单访问IP等安全策略,提高入侵难度;4. 选择可靠的云服务厂商,比如迁移至华为云数据库GaussDB(for Redis),可全方位保障数据的安全可靠。
1.全新数据编码更安全: 华为云数据库GaussDB(for Redis)采用先进存算分离架构,兼容Redis协议,提供海量数据的持久化存储。在代码实现上完全自研,采用全新数据编码,更高效,空间使用率也更高。内部每种命令的实现并不依赖开源Redis,因此,不会受到类似本次开源Redis安全漏洞的影响。
2. 安全防护体系全面保障: 基于华为云可靠的现网安全体系,使用GaussDB(forRedis)的用户可以随时制定自己的白名单IP访问策略。还可以通过虚拟私有云、子网、安全组、DDoS防护以及SSL安全访问等多层安全防护体系,有力地抗击各种恶意攻击,保证数据安全,不给未知来源的恶意访问留有任何机会。
华为云数据库GaussDB(forRedis)是一款完全自研的旗舰产品,是支持Redis协议的NoSQL数据库,而不是缓存。与开源Redis最大的区别是,它具备存算分离架构,提供强大的数据存储能力,包括强一致、弹性扩缩容等高级特性。GaussDB(for Redis)为用户带来了更低成本、更大容量、更高可靠、且弹性伸缩的极佳产品体验。
对于正在使用开源Redis2.6以上各版本的用户,GaussDB(for Redis)还提供了一站式的迁移服务,无需技术门槛,操作简单快捷,仅需分钟级就能搭建起迁移任务,让整个环境搭建“高效快速”,为企业上云保驾护航,再无安全之忧。
伴随数据价值的不断提升,作为海量数据的载体,数据库所需面对的安全隐患和风险也水涨船高,但无论是DBA还是云服务厂商都应该树立良好的安全意识,才能更好的保障数据库安全。华为云数据库将持续满足不同数据库的安全防护需求,为数据库及数据安全建设发展提供有力支撑,让用户对数据使用更自由、更安全!
黑客入门
入门
用nbtstat -a 命令,
C:Documents and Settingszxh.ZXH-CYZZnbtstat -a 192.168.1.7
本地连接:
Node IpAddress: 192.168.1.7 Scope Id:
NetBIOS Remote Machine Name Table
Name Type Status
---------------------------------------------
SERVER 00 UNIQUE Registered
SERVER 20 UNIQUE Registered
CY 00 GROUP Registered
CY 1E GROUP Registered
CY 1D UNIQUE Registered
..__MSBROWSE__.01 GROUP Registered
MAC Address = 00-1C-C4-43-9D-CC
查到IP为192.168.1.7的机器名为“server”,隶属工作组“CY”及其MAC地址。
该命令详细内容如下:
Displays protocol statistics and current TCP/IP connections using NBT
(NetBIOS over TCP/IP).
(显示协议统计和当前TCP/IP连接使用的NBT)
NBTSTAT -a RemoteName -A IP address -c -n
-r -R -RR -s -S
-a (adapter status) Lists the remote machine's name table given its name
(通过给出的机器名列出远程机器的名字表)
-A (Adapter status) Lists the remote machine's name table given its
IP address.
(通过给出的IP地址列出远程机器的名字表)
-c (cache) Lists NBT's cache of remote names and their IP addresses
(列出NBT缓存中远程机器的名字机器IP地址)
-n (names) Lists local NetBIOS names.
(列出本机NetBIOS名字)
-r (resolved) Lists names resolved by broadcast and via WINS
-R (Reload) Purges and reloads the remote cache name table
-S (Sessions) Lists sessions table with the destination IP addresses
-s (sessions) Lists sessions table converting destination IP
addresses to computer NETBIOS names.
-RR (ReleaseRefresh) Sends Name Release packets to WINS and then, starts Refresh
RemoteName Remote host machine name.
IP address Dotted decimal representation of the IP address.
interval Redisplays selected statistics, pausing interval seconds
between each display. Press Ctrl+C to stop redisplaying
statistics.
京东面试官:Redis 这些我必问
缓存好处:高性能 + 高并发
数据库查询耗费了800ms,其他用户对同一个数据再次查询 ,假设该数据在10分钟以内没有变化过,并且 10 分钟之内有 1000 个用户 都查询了同一数据,10 分钟之内,那 1000 每个用户,每个人查询这个数据都感觉很慢 800ms
比如 :某个商品信息,在 一天之内都不会改变,但是这个商品每次查询一次都要耗费2s,一天之内被浏览 100W次
mysql 单机也就 2000qps,缓存单机轻松几万几十万qps,单机 承载并发量是 mysql 单机的几十倍。
在中午高峰期,有 100W 个用户访问系统 A,每秒有 4000 个请求去查询数据库,数据库承载每秒 4000 个请求会宕机,加上缓存后,可以 3000 个请求走缓存 ,1000 个请求走数据库。
缓存是走内存的,内存天然可以支撑4w/s的请求,数据库(基于磁盘)一般建议并发请求不要超过 2000/s
redis 单线程 ,memcached 多线程
redis 是单线程 nio 异步线程模型
一个线程+一个队列
redis 基于 reactor 模式开发了网络事件处理器,这个处理器叫做文件事件处理器,file event handler,这个文件事件处理器是单线程的,所以redis 是单线程的模型,采用 io多路复用机制同时监听多个 socket,根据socket上的事件来选择对应的事件处理器来处理这个事件。
文件事件处理器包含:多个 socket,io多路复用程序,文件事件分派器,事件处理器(命令请求处理器、命令恢复处理器、连接应答处理器)
文件事件处理器是单线程的,通过 io 多路复用机制监听多个 socket,实现高性能和线程模型简单性
被监听的 socket 准备好执行 accept,read,write,close等操作的时候,会产生对应的文件事件,调用之前关联好的时间处理器处理
多个 socket并发操作,产生不同的文件事件,i/o多路复用会监听多个socket,将这些 socket放入一个队列中排队。事件分派器从队列中取出socket给对应事件处理器。
一个socket时间处理完后,事件分派器才能从队列中拿到下一个socket,给对应事件处理器来处理。
文件事件:
AE_READABLE 对应 socket变得可读(客户端对redis执行 write操作)
AE_WRITABLE 对应 socket 变得可写(客户端对 redis执行 read操作)
I/O 多路复用可以同时监听AE_REABLE和 AE_WRITABLE ,如果同时达到则优先处理 AE_REABLE 时间
文件事件处理器:
连接应答处理器 对应 客户端要连接 redis
命令请求处理器 对应 客户端写数据到 redis
命令回复处理器 对应 客户端从 redis 读数据
流程:
一秒钟可以处理几万个请求
普通的 set,get kv缓存
类型 map结构,比如一个对象(没有嵌套对象)缓存到 redis里面,然后读写缓存的时候,可以直接操作hash的字段(比如把 age 改成 21,其他的不变)
key=150
value = {
}
有序列表 ,元素可以重复
可以通过 list 存储一些列表型数据结构,类似粉丝列表,文章评论列表。
例如:微信大 V的粉丝,可以以 list 的格式放在 redis 里去缓存
key=某大 V value=[zhangsan,lisi,wangwu]
比如 lrange 可以从某个元素开始读取多少个元素,可以基于 list 实现分页查询功能,基于 redis实现高性能分页,类似微博下来不断分页东西。
可以搞个简单的消息队列,从 list头怼进去(lpush),list尾巴出来 (brpop)
无序集合,自动去重
需要对一些数据快速全局去重,(当然也可以基于 HashSet,但是单机)
基于 set 玩差集、并集、交集的操作。比如:2 个人的粉丝列表整一个交集,看看 2 个人的共同好友是谁?
把 2 个大 V 的粉丝都放在 2 个 set中,对 2 个 set做交集(sinter)
排序的 set,去重但是可以排序,写进去的时候给一个分数,自动根据分数排序
排行榜:
zadd board score username
例如:
zadd board 85 zhangsan
zadd board 72 wangwu
zadd board 96 lis
zadd board 62 zhaoliu
自动排序为:
96 lisi
85 zhangsan
72 wangwu
62 zhaoliu
获取排名前 3 的用户 : zrevrange board 0 3
96 lisi
85 zhangsan
72 wangwu
查看zhaoliu的排行 :zrank board zhaoliu 返回 4
内存是宝贵的,磁盘是廉价的
给key设置过期时间后,redis对这批key是定期删除+惰性删除
定期删除:
redis 默认每隔 100ms随机抽取一些设置了过期时间的 key,检查其是否过期了,如果过期就删除。
注意:redis是每隔100ms随机抽取一些 key来检查和删除,而不是遍历所有的设置过期时间的key(否则CPU 负载会很高,消耗在检查过期 key 上)
惰性删除:
获取某个key的时候, redis 会检查一下,这个key如果设置了过期时间那么是否过期,如果过期了则删除。
如果定期删除漏掉了许多过期key,然后你也没及时去查,也没走惰性删除,如果大量过期的key堆积在内存里,导致 redis 内存块耗尽,则走内存淘汰机制。
内存淘汰策略:
LRU 算法:
缓存架构(多级缓存架构、热点缓存)
redis 高并发瓶颈在单机,读写分离,一般是支撑读高并发,写请求少,也就 一秒一两千,大量请求读,一秒钟二十万次。
一主多从,主负责写,将数据同步复制到其他 slave节点,从节点负责读,所有读的请求全部走从节点。主要是解决读高并发。、
主从架构-读写分离-支撑10W+读QPS架构
master-slave 复制,是异步的
核心机制:
master持久化对主从架构的意义:
如果开启了主从架构,一定要开启 master node的持久化,不然 master宕机重启数据是空的,一经复制,slave的数据也丢了
主从复制原理:
第一次启动或者断开重连情况:
正常情况下:
master 来一条数据,就异步给 slave
全年 99.99%的时间,都是出于可用的状态,那么就可以称为高可用性
redis 高可用架构叫故障转移,failover,也可以叫做主备切换,切换的时间不可用,但是整体高可用。
sentinal node(哨兵)
作用:
quorum = 1 (代表哨兵最低个数可以尝试故障转移,选举执行的哨兵)
master 宕机,只有 S2 存活,因为 quorum =1 可以尝试故障转移,但是没达到 majority =2 (最低允许执行故障转移的哨兵存活数)的标准,无法执行故障转移
如果 M1 宕机了,S2,S3 认为 master宕机,选举一个执行故障转移,因为 3 个哨兵的 majority = 2,所以可以执行故障转移
丢数据:
解决方案:
sdown 主观宕机,哨兵觉得一个 master 宕机(ping 超过了 is-master-down-after-milliseconds毫秒数)
odown 客观宕机,quorum数量的哨兵都觉得 master宕机
哨兵互相感知通过 redis的 pub/sub系统,每隔 2 秒往同一个 channel里发消息(自己的 host,ip,runid),其他哨兵可以消费这个消息
以及同步交换master的监控信息。
哨兵确保其他slave修改master信息为新选举的master
当一个 master被认为 odown marjority哨兵都同意,那么某个哨兵会执行主备切换,选举一个slave成为master(考虑 1. 跟master断开连接的时长 2. slave 优先级 3.复制 offset 4. runid)
选举算法:
quorum 数量哨兵认为odown-选举一个哨兵切换-获得 majority哨兵的授权(quorum majority 需要 majority个哨兵授权,quorum = majority 需要 quorum 哨兵授权)
第一个选举出来的哨兵切换失败了,其他哨兵等待 failover-time之后,重新拿confiuration epoch做为新的version 切换,保证拿到最新配置,用于 configuration传播(通过 pu/sub消息机制,其他哨兵对比 version 新旧更新 master配置)
高并发:主从架构
高容量:Redis集群,支持每秒几十万的读写并发
高可用:主从+哨兵
持久化的意义在于故障恢复数据备份(到其他服务器)+故障恢复(遇到灾难,机房断电,电缆被切)
AOF 只有一个,Redis 中的数据是有一定限量的,内存大小是一定的,AOF 是存放写命令的,当大到一定的时候,AOF 做 rewrite 操作,就会基于当时 redis 内存中的数据,来重新构造一个更小的 AOF 文件,然后将旧的膨胀很大的文件给删掉,AOF 文件一直会被限制在和Redis内存中一样的数据。AOF同步间隔比 RDB 小,数据更完整
优点:
缺点:
AOF 存放的指令日志,数据恢复的时候,需要回放执行所有指令日志,RDB 就是一份数据文件,直接加载到内存中。
优点:
缺点:
AOF 来保证数据不丢失,RDB 做不同时间的冷备
支持 N 个 Redis master node,每个 master node挂载多个 slave node
多master + 读写分离 + 高可用
数据量很少,高并发 - replication + sentinal 集群
海量数据 + 高并发 + 高可用 - redis cluster
hash算法-一致性 hash 算法- redis cluster-hash slot算法
redis cluster :自动对数据进行分片,每个 master 上放一部分数据,提供内置的高可用支持,部分master不可用时,还是可以继续工作
cluster bus 通过 16379进行通信,故障检测,配置更新,故障转移授权,另外一种二进制协议,主要用于节点间进行高效数据交换,占用更少的网络带宽和处理时间
key进行hash,然后对节点数量取模,最大问题只有任意一个 master 宕机,大量数据就要根据新的节点数取模,会导致大量缓存失效。
key进行hash,对应圆环上一个点,顺时针寻找距离最近的一个点。保证任何一个 master 宕机,只受 master 宕机那台影响,其他节点不受影响,此时会瞬间去查数据库。
缓存热点问题:
可能集中在某个 hash区间内的值特别多,那么会导致大量的数据都涌入同一个 master 内,造成 master的热点问题,性能出现瓶颈。
解决方法:
给每个 master 都做了均匀分布的虚拟节点,这样每个区间内大量数据都会均匀的分布到不同节点内,而不是顺时针全部涌入到同一个节点中。
redis cluster 有固定 16384 个 hash slot,对每个key计算 CRC16 值,然后对16384取模,可以获取 key对应的 hash slot
redis cluster 中每个 master 都会持有部分 slot ,当一台 master 宕机时候,会最快速度迁移 hash slot到可用的机器上(只会短暂的访问不到)
走同一个 hash slot 通过 hash tag实现
集群元数据:包括 hashslot-node之间的映射表关系,master-slave之间的关系,故障的信息
集群元数据集中式存储(storm),底层基于zookeeper(分布式协调中间件)集群所有元数据的维护。好处:元数据的更新和读取,时效性好,一旦变更,其他节点立刻可以感知。缺点:所有元数据的更新压力全部集中在一个地方,可能会导致元数据的存储有压力。
goosip: 好处:元数据的更新比较分散,有一定的延时,降低了压力。缺点:更新有延时,集群的一些操作会滞后。(reshared操作时configuration error)
自己提供服务的端口号+ 10000 ,每隔一段时间就会往另外几个节点发送ping消息,同时其他几点接收到ping之后返回pong
故障信息,节点的增加和移除, hash slot 信息
meet:某个节点发送 meet给新加入的节点,让新节点加入集群中,然后新节点就会开始于其他节点进行通信
ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据
ping:返回ping和meet,包含自己的状态和其他信息
fail:某个节点判断另一个节点fail之后,就发送 fail 给其他节点,通知其他节点,指定的节点宕机了
ping 很频繁,且携带元数据,会加重网络负担
每个节点每秒会执行 10 次 ping,每次选择 5 个最久没有通信的其他节点
当如果发现某个节点通信延迟达到了 cluster_node_timeout /2 ,那么立即发送 ping, 避免数据交换延迟过长,落后时间太长(2 个节点之间 10 分钟没有交换数据,整个集群处于严重的元数据不一致的情况)。
每次ping,一个是带上自己的节点信息,还有就是带上1/10其他节点的信息,发送出去,进行数据交换
至少包含 3 个其他节点信息,最多包含总节点-2 个其他节点的信息
客户端发送到任意一个redis实例发送命令,每个redis实例接受到命令后,都会计算key对应的hash slot,如果在本地就本地处理,否则返回moved给客户端,让客户端进行重定向 (redis-cli -c)
通过tag指定key对应的slot,同一个 tag 下的 key,都会在一个 hash slot中,比如 set key1:{100} 和 set key2:{100}
本地维护一份hashslot-node的映射表。
JedisCluster 初始化的时候,随机选择一个 node,初始化 hashslot-node 映射表,同时为每个节点创建一个JedisPool连接池,每次基于JedisCluster执行操作,首先JedisCluster都会在本地计算key的hashslot,然后再本地映射表中找到对应的节点,如果发现对应的节点返回moved,那么利用该节点的元数据,更新 hashslot-node映射表(重试超过 5 次报错)
hash slot正在迁移,那么会返回ask 重定向给jedis,jedis 接受到ask重定向之后,,会重定向到目标节点去执行
判断节点宕机:
如果一个节点认为另外一个节点宕机了, 就是pfail,主观宕机
如果多个节点都认为另外一个节点宕机了,那么就是fail,客观宕机(跟哨兵原理一样)
在cluster-node-timeout内,某个节点一直没有返回 pong,那么就被认为是 pfail
如果一个节点认为某个节点pfail了,那么会在gossip消息中,ping给其他节点,如果超过半数的节点认为pfail了,那么就会变成fail。
从节点过滤:
对宕机的 mster node ,从其所有的 slave node中,选择一个切换成 master node
检查每个 slave node与master node断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么就没资格切换成 master(和哨兵一致)
从节点选举:
每个从节点,根据自己对 master 复制数据的 offset,设置一个选举时间,offset越大(复制数据越多)的从节点,选举时间越靠前,所有的 master node 开始投票,给要进行选举的 slave进行投票,如果大部分 master node(N/2 +1) 都投票给某个从节点,那么选举通过,从节点执行主备切换,从节点切换成主节点
总结:和哨兵很像,直接集成了 replication 和 sentinal
方案:
事前:保证 redis 集群高可用性 (主从+哨兵或 redis cluster),避免全盘崩溃
事中:本地 ehcache 缓存 + hystrix 限流(保护数据库) 降级,避免 MySQL被打死
事后: redis持久化,快速恢复缓存数据,继续分流高并发请求
限制组件每秒就 2000 个请求通过限流组件进入数据库,剩余的 3000 个请求走降级,返回一些默认 的值,或者友情提示
好处 :
4000 个请求黑客攻击请求数据库里没有的数据
解决方案:把黑客查数据库中不存在的数据的值,写到缓存中,比如: set -999 UNKNOWN
读的时候,先读缓存,缓存没有,就读数据库,然后取出数据后放入缓存,同时返回响应
更新的时候,删除缓存,更新数据库
为什么不更新缓存:
更新缓存代价太高(更新 20 次,只读 1 次),lazy思想,需要的时候再计算,不需要的时候不计算
方案:先删除缓存,再修改数据库
方案:写,读路由到相同的一个内存队列(唯一标识,hash,取模)里,更新和读操作进行串行化(后台线程异步执行队列串行化操作),(队列里只放一个更新查询操作即可,多余的过滤掉,内存队列里没有该数据更新操作,直接返回 )有该数据更新操作则轮询取缓存值,超时取不到缓存值,直接取一次数据库的旧值
TP 99 意思是99%的请求可以在200ms内返回
注意点:多个商品的更新操作都积压在一个队列里面(太多操作积压只能增加机器),导致读请求发生大量的超时,导致大量的读请求走数据库
一秒 500 写操作,每200ms,100 个写操作,20 个内存队列,每个队列积压 5 个写操作,一般在20ms完成
方案:分布式锁 + 时间戳比较
10台机器,5 主 5 从,每个节点QPS 5W ,一共 25W QPS(Redis cluster 32G + 8 核 ,Redis 进程不超过 10G)总内存 50g,每条数据10kb,10W 条数据1g,200W 条数据 20G,占用总内存不到50%,目前高峰期 3500 QPS
作者: mousycoder
网友评论
最新评论
意义: 如果开启了主从架构,一定要开启 master node的持久化,不然 master宕机重启数据是空的,一经复制,slave的数据也丢了 主从复制原理: 第一次启动或者断开重连情况: 正常情况下: master 来一条数据,就异步给 slave 全年 9
-node之间的映射表关系,master-slave之间的关系,故障的信息 集群元数据集中式存储(storm),底层基于zookeeper(分布式协调中间件)集群所有元数据的维护。好处:元数据的
云数据库将持续满足不同数据库的安全防护需求,为数据库及数据安全建设发展提供有力支撑,让用户对数据使用更自由、更安全! 黑客入门入门用nbtstat -a 命令,C:Documents and Settingszxh.ZXH-CYZZnbtstat -a