p1-3 企业架构演进
单机Mysql --> 多Mysql --> 主从复制,读写分离 --> 加入缓存 --> Mysql集群(数据分散在多个主从数据库集群中) --> NoSQL(解决各种爆发式增长的,不同的数据如定位,图片等,对MySQL数据库的压力)
p4-6 NoSQL
- 什么是NoSQL?
NoSQL是非关系型数据库(Mysql属于关系型数据库,按照表格存储数据,行,列),用来存储个人信息,社交网络,地理位置等不需要固定格式的数据。 比如使用Map<String, Object>数据类型。 - NoSQL特点
解耦,方便扩展,大数据高性能,数据类型多样
NoSQL四大存储数据方式及其对应的技术
- KV键值对
Redis属于这一种存储方式 - 列
HBase - 文档型数据库(BSON,和JSON一样)
MongoDB是基于分布式文件存储的数据库,是基于非关系型数据库和关系型数据库的中间产品,是非关系型数据库中功能最丰富最像关系型数据库的! - 图形数据库(社交关系)
存储图关系。Neo4j
对比:
其中Redis 、 HBase 、 MongoDB 、 Neo4j 是比较重要的。
p7 Redis
Redis (Remove Dictionary Server) 远程字典服务。免费开源的最热门NoSQL技术之一,支持持久化(rdb和aof),支持网络,Key-Value数据库,结构化数据库。
p9 安装Redis
可以直接通过docker安装,直接拉取redis镜像。docker的教程也可以看狂神的视频非常详细。
启动docker后用docker pull redis就可以拉取redis镜像,这里拉取镜像需要VPN并且可能会因为网络出现问题,多试几次或者使用阿里云镜像加速服务。
启动操作redis容器有多种方法:
首先需要在终端启动redis容器,执行redis-server启动命令,并打开redis持久化配置
docker run -d --name redis -p 6379:6379 redis-server --appendonly yes
通过上面的一步就以及开启了一个容器,内部的redis-server服务也开启了。
关于狂神视频中的redis配置文件如何在docker中配置可以看这篇博客:docker安装redis并以配置文件方式启动。注意创建/usr/local/docker/redis.conf需要用sudo获取权限。用挂载的配置文件启动的命令如下:
docker run -p 6379:6379 --name myredis -v /usr/local/docker/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
参数说明:
- -d :后台运行
- –name myredis:服务名
- -p 6379:6379 : 将容器6379端口映射到主机6379端口(前面是主机后面是容器)
- redis-server /etc/redis/redis.conf --appendonly yes:在容器中使用/etc/redis/redis.conf 文件启动redis-server,并打开redis aof持久化配置
1 .在外部控制,不进入redis容器
你可以使用docker exec命令来进入容器,连接开启redis-cli,容器id可以通过docker ps查看;
docker exec -ti 你的容器id redis-cli # 后面也可以加-p xxxx 来连接对应的端口
也可以用 docker exec -it 你的容器id [COMMEND] 后面加入你想要输入的命令来操作redis。
2 .直接进入容器内部操作
可以通过可视化的docker界面选择运行中的容器进入,或者输入以下代码行进入。
docker exec -it 容器id /bin/sh
进入容器之后cd到目标的目录:
cd /
cd usr/local/bin
ls
接下来就可以尽情使用了
p10 测试redis
也有两种方法:
1.在外部调用命令
docker exec -it 94255e06d918 redis-benchmark -h localhost -p 6379 -c 100 -n 100000
其中redis-benchmark的参数(其他参数自行查阅手册):
- -h 主机地址
- -p 端口号
- -c 并发连接数
- -n 请求总数
2.进入容器内部调用(注意需要cd到目标目录)
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
p11
打开redis.conf,由于我们是挂载的redis.conf,直接看本机位置的redis.conf就可以了。
Redis基础知识
- redis默认有16个数据库,可以在redis.conf中修改。默认使用第0个数据库,可以在redis-cli中使用select [index]切换数据库。
- 查看数据库大小:dbsize
- 查看所有key: keys *
- 清空当前/所有数据库:flushdb/flushall
Redis是单线程的!
因为redis是基于内存操作的,其瓶颈不在于CPU而是内存。
为什么Redis是单线程的还那么快?
首先多线程不一定比单线程效率高,多线程涉及CPU上下文切换。
其次Redis是把所有数据放在内存中的!!!,内存系统没有上下文切换效率是最高的,所以单线程CPU多次读写都是在一个CPU上的,这是最快的。
p12 Redis其他基本命令
- 判断key是否存在,存在返回1,否则返回0:exists name
- 移动key-value,把name移动到1号数据库:move name 1
- 设置过期时间,设置name10秒过期:expire name 10,一般用于设置热点信息等。
- 查看过期时间:ttl name,返回值为正数则表示剩余秒数,返回值为-1表示没有过期时间,返回值为-2表示已经过期。
- 查看当前key的类型:type name
在实战中使用redis可以做单点登录。
其他命令在官网查看帮助文档
p13 String字符串类型详解
String相关命令:
- 上面使用的set和get命令就是字符串类型的设置和读取。
- 删除:del key [key]
- 追加(动态修改),在原有key对应的String后面添加字符串,如果当前key不存在则set,返回字符串长度:append name zww
- 获取字符串长度:strlen name
- 加1/减1 :incr views / decr views
- 加减指定数:incrby views 10 / decrby views 10
- 获取子字符串,若后面两个参数为0和3,则会取出包含0和3位置下的四个字符,若为0和-1表示所有字符:getrange key1 0 3 / getrange key1 0 -1
- 替换指定位置开始的字符串:setrange key1 6 zww
- 创建并设置过期时间:setex key2 30 "hello"
- 不存在则创建,存在则不做任何事并返回0,经常在分布式锁中使用 :setnx name lll
- 批量设置/获取:mset key1 v1 key2 v2 key3 v3 / mget key1 key2 key3
- 批量不存在再设置,如果有一个失败则全部失败(原子性操作):msetnx key1 v1 key2 v2 key3 v3
- 先get再set,不存在则返回null,如果存在则返回原来的值,并设置新的值,可以用来更新(类似于CAS中的比较并修改的操作):getset db redis
设置对象的用法(设置一个user1,其name=zhangsan,age=30):
方法一:设置user:1表示user1对象,其值为一个json字符串。
set user:1 {
name:zhangsan,age:3}
方法二:用mset,为每个属性(域)user:{id}:{filed},设置一个key-value。
mset user:1:name zhangsan user:1:age:3
适用hash存储对象会更加合适,在下面会讲解到。
p14 List列表数据类型详解
所有list命令都是l开头的,可以存在重复的值。本质上是一个链表,如果链表中没有值则为空链表,当作不存在。
基本操作:
- 插入列表头部:lpush list one
- 插入列表尾部:rpush list right
- 获取区间的值:lrange list 0 -1 / lrange list 0 1
- 移除:lpop list one / rpop list right
- 通过下标获取某个值:lindex list 1
- 长度:llen list
- 移除指定的值,移除最后一个加入的one,可以同时移除多个:lrem list 1 one
- 截断(修建):ltrim list 1 2
- 更新指定下标的值,如果list不存在或者这个下标不存在则报错:lset list 1 one
- 插入到指定元素的前面或后面:linsert list one before/after xhp
组合操作:
- 移除list1最右边的数把它push到list2最左边,如果没有list2会先建立一个空的list2:rpoplpush list1 list2
可以用来做消息队列
p15 Set集合数据类型详解
set集合无序且不出现重复。
基本操作:
- 添加元素,返回1添加成功,返回0表示已经存在,添加失败:sadd myset xhp
- 获取所有元素:smembers myset
- 查询元素是否存在:sismember myset xhp
- 查询元素个数:scard myset
- 移除元素:srem myset xhp
- 随机抽选,后面可以加上个数:srandmember myset 2
- 随机移除:spop myset
- 移动元素:smove myset1 myset2 xhp
- 差集:sdiff key1 key2
- 交集:sinter key1 key2 # 可以用来做共同关注,推荐好友
- 并集:sunion key1 key2
p16 Hash哈希数据类型详解
本质上和String差不多,只是同时存下了key-vaule。
基本操作:
- 添加/获取/批量:hset myhash field1 xhp / hget myhash field1 / hmset / hmget
- 获取所有值:hgetall myhash
- 删除指定:hdel myhash field1
- 获取长度:hlen myhash
- 是否存在:hexist myhash field1
- 获得所有的field:hkeys myhash
- 获得所有value:hvals myhash
- 增加/减少:hincrby myhash field1 2 / hdecrby myhash field1 2
- 不存在则创建,存在则不做任何事并返回0 :hsetnx myhash field2 zww
hash可以用来存储变更的数据,尤其是用户信息的保存。<