Java技术的发展路线
1、解决功能性的问题。
2、解决扩展性的问题。(耦合度低,扩展性更强),框架就出现了,尽量减少重复代码。
3、解决性能的问题。无法承受高并发访问
互联网发展所面临的问题
web1.0 单向提供信息。比如新闻网,网络数据量很小
web2.0 双向提供信息,网站的用户也会为网站提供信息,如评论,点赞,转发
互联网三高:
1.高并发(QPS每秒的访问量)、大流量。
2.高可用,就是要保证服务器能够尽量多的时间为用户提供服务,也就是服务器不能停机维护。
3.海量数据(大数据)涉及到大数据的存储、大数据的分析
解决问题的思路:
1.解决CPU和内存压力问题
搭建服务器的集群
集群面临数据一致性的问题。如session共享问题
方案1:session复制,不好,因为数据重复冗余,复制session影响服务器本身的性能
方案2:一致性hash
每个用户都有ip和机器码。负载均衡,对同一个用户多次请求都发给同一个服务器
缺点:万一这台服务器挂了
方案3:不使用session,使用cookie存储登录的用户信息
缺点:增加了网络传输的数据量、浏览器禁用cookie会失效
方案4:使用session服务器
将session存在内存的话,效率很高。
2. 解决磁盘IO压力问题
mysql数据存在硬盘,数据量大的话,会持续磁盘io。怎么降低磁盘io?
NoSQL是Not only SQL的缩写,大意为“不只是SQL”,对sql的补充,而不是替代!
非关系型数据库三剑客:
MemCache、Redis、MongoDB
关系型数据库和非关系型数据库的对比
用老师的话说:到处都是区别,没有相同的点
对比项 | 关系型数据库 | 非关系型数据库 |
---|---|---|
数据存储位置 | 硬盘 | 内存 |
数据结构 | 高度组织化结构化数据(建库,建表) | 没有预定义的模式(没有表) |
数据操作方式 | SQL | 所有数据都是键值对,没有声明性查询语言 |
事务控制 | 严格的基于事务ACID原则 | 基于乐观锁的松散事务控制 |
访问控制 | 细粒度的用户访问权限控制 | 简单的基于IP绑定或密码的访问控制(讲究的效率,存的数据不重要,删了就删了) |
外键 | 支持(表与表之间的关系) | 不支持 |
索引 | 支持(提高查询速度) | 不支持(在内存操作,速度已经飞快) |
所以NoSQL数据库的最大优势体现为:高性能(速度快、效率高)、高可用性(非关系型数据库可以更好搭建高可用集群)和可伸缩性(灵活,没有表)
非关系型数据库的适用场景
对数据高并发的读写
海量数据的读写
对数据高可扩展性的
非关系型数据库不适用的场景
需要事务支持(事务控制)
基于sql的结构化查询存储,处理复杂的关系,需要多表查询。(处理多表的复杂关系)
redis
c语言编写的,存储在内存中,以键值对操作数据
官方给出的性能参考(在并发量50的情况下):
GET: 110000/s:读的速度每秒11万次
SET: 81000/s: 写的速度每秒8万次
Redis命令参考文档网址:Redis 命令参考 — Redis 命令参考
redis使用场景:
1.配合关系型数据库做高速缓存(高频次、数据很少变化,如商品详情)
2.数据临时存储位置,token就可以在Redis中临时存储
3.作为分布式环境下解决Session不一致问题时的Session库
4.多样的数据结构存储持久化数据,redis中能存储8种类型的数据
安装Linux版本的Redis
官方只提供linux版本的redis
安装步骤
1.将redis压缩包上传到虚拟机的/usr/local
目录中
2. 安装c语言的编译环境
因为是Redis是c语言开发的,所以要运行redis必须有c语言编译环境
yum install gcc-c++ -y
# 安装GCC环境,中间有确认的话,一律选y (yes)
# 注意:使用yum命令安装软件,需要联网
3.解压redis
进入/usr/local
目录: cd /usr/local
解压: tar -xvf redis-5.0.13.tar.gz
4.重命名文件夹
将 redis-5.0.13
重命名成redis
mv redis-5.0.13 redis
5.编译安装
进入redis目录:cd redis/
编译redis:make
指定安装路径并且安装: make PREFIX=/usr/local/redis install
,安装好之后/usr/local/redis
目录中会多出来一个bin
目录
redis的配置和启动
1.将/usr/local/redis/redis.conf
配置文件拷贝到/usr/local/redis/bin
目录中
cp /usr/local/redis/redis.conf /usr/local/redis/bin
2.创建一个redis的日志存储目录
mkdir /var/logs
3.使用vim
编辑器修改bin
目录中的redis.conf
文件,修改如下三项
vim /usr/local/redis/bin/redis.conf
修改时,可以使用/搜索,n/N切换下一个适配项
daemonize=no,启动的就是前台进程。mysql和tomcat就是后台进程
配置项名称 作用 取值 daemonize 控制是否以守护进程形式运行Redis服务器 yes logfile 指定日志文件位置 "/var/logs/redis.log" dir Redis工作目录 /usr/local/redis
1.后台启动redis服务器
可执行文件,写相对路径就能执行
进入redis的bin目录: cd /usr/local/redis/bin
让redis根据配置文件启动: ./redis-server ./redis.conf
2.启动redis客户端连接服务器
./redis-cli
然后执行
ping
命令,如果能连接上,代表redis安装成功(pong),并且redis服务器启动成功
安装Redis可视化客户端
该客户端装在物理机
但是因为redis默认不允许远程连接
需要修改Linux中的Redis服务器的配置: 在redis.conf配置文件中在bind的值的后面加上虚拟机的IP地址(在后面将Jedis的时候会讲到),并且要确保Linux的防火墙放行了"6379"端口,或者防火墙关闭了
例如:原本的是
bind 127.0.0.1
现在改成
bind 127.0.0.1 192.168.2.108或者直接改成 0.0.0.0也行
改完之后要重启redis:
1.在redis客户端中执行shutdown命令(关闭redis服务端)
关闭 redis客户端,exit
2.杀进程
先找到redis服务的进程id
ps -ef | grep redis
然后根据进程id杀死进程
kill -9 进程id
Redis中的数据,总体上是键值对,不同数据类型指的是键值对中值的类型,其中value支持8种数据类型
数据类型 | 应用场景 |
---|---|
string | 分布式Session存储 分布式数据库ID 计数器:统计网站访问量 |
hash | 存储对象信息(购物车中的商品信息) 存储表的信息 |
list | 实现队列、栈操作 汇总日志 粉丝列表 关注的人列表 |
set | 签到 打卡 点赞 |
zset | 排行榜 百度热点搜索 |
geospatial | 获取地理位置信息 两地之间的距离 |
hyperloglogs | 基数统计 |
bitmaps | 统计用户访问次数 |
8中数据类型简介
redis基本操作命令
1.切换数据库(默认使用db0)
Redis默认有16个数据库,默认情况下使用的是第一个数据库,我们使用select进行切换,数据库索引从0开始
select 1
2.查看某个数据库的键值对个数
dbsize
3.清空数据库
flushdb 清空当前数据库
flushall 清空所有数据库
redis key操作
key的命名
1.用英文,绝对不能中文。key的命名不能超过1024个字节、1024个字符
2.要做到见名知意
3.多个单词用:分割。例如:“user:token:session:id” 。 java中驼峰,mysql用_
4.Redis命令不区分大小写,但是key和值区分大小写
KEY操作相关命令
命令 | 描述 |
---|---|
KEYS PATTERN | 把匹配PATTERN的key返回。PATTERN中可以使用“*”匹配多个字符,使用“?”匹配单个字符 |
TYPE KEY | 返回KEY对应的值的类型 |
MOVE KEY DB | 把一组键值对数据移动到另一个数据库中 |
DEL KEY [KEY ...] [重点] | 根据KEY进行删除,至少要指定一个KEY |
EXISTS KEY [KEY ...] | 检查指定的KEY是否存在。指定一个KEY时,存在返回1,不存在返回0。可以指定多个,返回存在的KEY的数量。 |
RENAME KEY NEWKEY | 重命名一个KEY,NEWKEY不管是否是已经存在的都会执行,如果NEWKEY已经存在则会被覆盖。 |
RENAMENX KEY NEWKEY | 只有在NEWKEY不存在时能够执行成功,否则失败 |
TTL KEY | 以秒为单位查看KEY还能存在多长时间 正数:剩余的存活时间(单位:秒) -1:永不过期 -2:不存在的Key |
EXPIRE KEY SECONDS [重点] | 给一个KEY设置在SECONDS秒后过期,过期会被Redis移除。 |
PERSIST KEY | 移除过期时间,变成永久key |
演示一个:
keys 正则表达式.根据正则去匹配
查询数据库中所有的key
string操作
偏移量offet4,跳过4个字符
命令 | 描述 |
---|---|
SET key value(重点) | 设置指定 key 的值 |
GET key(重点) | 获取指定 key 的值 |
APPEND KEY VALUE | 把指定的value追加到KEY对应的原来的值后面,返回值是追加后字符串长度 |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
GETRANGE KEY START END | 从字符串中取指定的一段,索引从0开始 START是开始取值的索引 END是结束取值的索引 |
SETRANGE KEY OFFSET VALUE | 跳过offset个字符,然后使用Value替换等长度的内容 |
STRLEN KEY | 直接返回字符串长度 |
SETEX key seconds value(重点) | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
SETNX key value(重点) | 只有在 key 不存在时设置 key 的值。 |
INCR key(重点) | 将 key 中储存的数字值增一。 |
INCRBY key increment | 将 key 所储存的值加上给定的增量值(increment) 。 |
DECR key | 将 key 中储存的数字值减一。 |
DECRBY key decrement | key 所储存的值减去给定的减量值(decrement)。 |
MSET KEY VALUE [KEY VALUE ...] | 一次性设置一组多个键值对 |
MGET KEY [KEY ...] | 一次性指定多个KEY,返回它们对应的值,没有值的KEY返回值是(nil |
MSETNX KEY VALUE [KEY VALUE ... | 一次性新建多个值 |
list操作
redis中的list是一个字符串列表,有顺序的。左边是头,右边是尾,底层是双链表
trim 修剪 去掉俩边的,保留中间的
命令 | 命令描述 |
---|---|
LPUSH key value [value ...] 重点 | 将一个或多个值插入到列表头部(左边) |
LPUSHX key value... | 只能针对存在的list执行LPUSH |
RPUSH key value [value ...] 重点 | 在列表中添加一个或多个值(右边) |
LRANGE key start stop | 根据list集合的索引打印元素数据 正着数:0,1,2,3,... 倒着数:-1,-2,-3,... |
LPOP key 重点 | 左边弹出一个 相当于移除第一个 |
RPOP key 重点 | 右边弹出一个 相当于移除最后一个 |
LLEN key | 返回指定key所对应的list中元素个数 |
LINDEX key index | 通过索引获取列表中的元素 |
LINSERT key BEFORE| AFTER pivot value | 在pivot指定的值前面或后面插入value 如果pivot值有重复的,那么就从左往右数,以第一个遇到的pivot为基准 BEFORE表示放在pivot前面 AFTER表示放在pivot后面 |
RPOPLPUSH source destination | 从source中RPOP一个元素,LPUSH到destination中 |
LREM key count value | 根据count指定的数量从key对应的list中删除value 具体执行时从左往右删除,遇到一个删一个,知道删除掉count个为止,如果整个列表中没有count个要删除的元素,就删完为止 |
LSET key index value | 把指定索引位置的元素替换为另一个值 |
LTRIM key start stop | 仅保留指定区间的数据,两边的数据被删除 |
set操作
该字符串集合中的字符串是无序的、唯一的
命令 | 命令描述 |
---|---|
SADD key member [member ...] 重点 | 给key指定的set集合中存入数据,set会自动去重 |
SREM key member [member ...] 重点 | 从集合中删除元素 |
SMEMBERS key | 返回可以指定的set集合中所有的元素 |
SCARD key | 返回集合中元素的数量 |
SISMEMBER key member | 检查当前指定member是否是集合中的元素 返回1:表示是集合中的元素 返回0:表示不是集合中的元素 |
SPOP key | 移除并返回集合中的一个随机元素 |
SDIFF key [key ...] 重点 | 将指定的集合执行“差集”操作 集合A:a,b,c 集合B:b,c,d A对B执行diff:a 相当于:A-交集部分 |
SDIFFSTORE destination key [key ...] | 取差集后存入destination这个集合 |
SUNION key [key ...]重点 | 将指定的集合执行“并集”操作 集合A:a,b,c 集合B:b,c,d 并集:a,b,c,d |
SUNIONSTORE destination key [key ...] | 取并集后存入destination这个集合 |
SINTER key [key ...]重点 | 将指定的集合进行“交集”操作 集合A:a,b,c 集合B:b,c,d 交集:b,c |
SINTERSTORE destination key [key ...] | 取交集后存入destination这个集合 |
SMOVE source destination member | 把member从source移动到destination |
Hash操作
hash类型本身也是一组键值对。比如将用户信息存储到redis中,用户信息中要包含用户的username、password、address、age。
json字符串可以但是不太好。
命令 | 命令描述 |
---|---|
HSET key field value | 将哈希表 key 中的字段 field 的值设为 value |
HMSET key field value [field value ...] 重点 | 同时将多个 field-value (字段-值)对设置到哈希表 key 中 |
HGET key field | 获取存储在哈希表中指定字段的值 |
HMGET key field [field ...] 重点 | 获取多个给定字段的值 |
HDEL key field [field ...] | 删除一个或多个哈希表字段 |
HLEN key | 获取哈希表中字段的数量 |
HGETALL key 重点 | 获取在哈希表中指定 key 的所有字段和值 |
HKEYS key | 获取所有哈希表中的字段 |
HVALS key | 获取哈希表中所有值 |
HEXISTS key field | 判断是否存在某个字段 |
zset(sorted set)操作
offest 跳过几个 偏移量
命令 | 命令描述 |
---|---|
ZADD key score member [score member ...] 重点 | 增加元素 |
ZSCORE key member | 获取元素的分数 |
ZREM key member [member ...] | 删除元素 |
ZCARD key | 获得集合中元素的数量 |
ZRANGE key start stop[WITHSCORES] 重点 | 获得排名在某个范围的元素列表 |
ZREVRANGE key start stop 重点 | 按照分数从高到低排序 |
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 重点 | 在分数的指定区间内返回数据 min参数可以通过 -inf 表示负无穷 max参数可以通过 +inf 表示正无穷 |
ZRANK key member | 先对分数进行升序排序,返回member的排名。排名从0开始 |
Geospatial
查询经纬度数据的网址:城市经纬度查询-国内城市经度纬度在线查询工具
添加地理位置
获取指定地区的坐标值
计算两地之间的直线距离
以给定坐标为中心,在指定半径内查找元素
HyperLogLogs
基数的概念:一个集合中不重复元素的个数
例如:集合{1,2,5,1,7,2,5}中元素个数是7,但是基数是4。而hyperloglogs的主要功能就是进行基数统计。
bitmap位图
直接对数据的二进制位进行操作 :
setbit设置指定比特位
getbit获取指定比特位
bitcount统计所有比特位中1的数量