nosql
为什么使用nosql
1.mysql单表超过300万条数据就一定要建索引(B+tree),否者查询会相对很慢
2.访问量(读写混合),一个服务器承受不了
早期因为网站用户少,数据量小,所以使用的都是单个mysql数据库处理处理所有数据,但是一旦用户量大,数据量多了mysql就无法承受巨大的访问压力,虽然可以通过一些优化手段进行优化但仍然不能达到最佳效果,比如索引,读写分离,集群等
后出现memcached(缓存),用于减轻数据库的压力
用户查询数据先去cache中查询,cache中没有然后再去数据库中查询,第一个集群节点没有再去第二个,查出来后在存到cahce中
早期mysql使用的是myisam引擎,现在使用的是innodb
MyISAM:表锁(当去查询一条数据时,将整个表都锁起来,其线程无法操作,十分影响效率,在高并发情况下十分影响效率)
INNODB:行锁(锁定一行数据)
分库分表解决写的压力
为什么redis是一个单线程的nosql数据库还这么快?
nosql(not only sql)
Redis入门
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
也被人们称之为结构化数据库!
redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步
读的速度是110000次/s,写的速度是81000次/s
Redis能干嘛?
1.内存存储,持久化,内存中断电即失,所以说持久化很重要(rdb/aof)
2.效率高,可以用于高速缓存
3.发布订阅系统(简单的消息队列)
4.地图信息分析
5.计时器,计数器(浏览量…)
6…
特性
1.多样的数据类型
2.持久化
3.集群
4.事务
…
学习中需要用到的东西
linux安装
windows输入命令:ping回车显示pong表示连接成功
linux
1.下载安装包
2.上传解压redis安装包(一般放在/opt目录下)
tar -zxvf redis-5.0.8.tar.gz
3.进入解压后的文件,会有redis的配置文件
4.基本对的环境安装
yum install gcc-c++ gcc -v(查看版本) make
5.redis默认安装路径 /usr/local/bin
6.将redis的配置文件复制
cp /opt/redis-5.0.8/redis.conf itstom cd itstom/ ls
7.redis默认不是后台启动的,修改配置文件
vim redis.conf 将daemonize no 改为yes(这样以后启动就是以后台方式启动了)
8.启动redis服务
redis-server itstom/redis.conf (通过指定对的配置温家岸启动)
9.使用redis-cli进行连接测试
10.查看redis的进程是否开启
ps -ef|grep redis
11.关闭redis服务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Ai8TUru-1620892088488)(/1620660488155.png)]
12.再次查看进程是否存在,确认是否关闭
##redis性能
基础知识
redis默认有16个数据库,默认使用第0个
可以使用select进行数据库切换
127.0.0.1:6379>select 3 #切换数据库
127.0.0.1:6379>select 0 #切换到0号数据库
127.0.0.1:6379[3]>DBSIZE #查看DB大小
(integer)0
127.0.0.1:6379[3]>keys * #查看当前数据库所有的key
127.0.0.1:6379[3]>flushdb #清空当前库
127.0.0.1:6379[3]>FLUSHALL #清空所有库
为什么redis的端口号是6379?
一个明星名字的缩写(粉丝效应)
redis是单线程的
多线程的瓶颈是CPU,但是redis是单线程的所以影响redis效率的是内存,redis是基于内存操作,redis的瓶颈是根据机器的内存和网络的带宽,既然可以使用单线程操作就没必要使用多线程,所以就选择使用单线程
Redis是C语言写的,每秒的qps是10万+
Redis单线程为什么这么快?
1.误区1:高性能的服务器一定是多线程的?
2.误区2:多线程(CPU上下文切换)一定比单线程快
速度:CPU>内存>硬盘
核心:redis是将数据放在内存中的,所以说使用单线程操作效率最高,多线程(CPU上下文切换,这是一个 耗时操作),
对于内存系统来说没有上下文切换效率也是最高的,多次读写都是在一个CPU上的
五大数据类型
127.0.0.1:6379>exits name #判断某个key是否存在
(integer) 1 #存在
127.0.0.1:6379>exits name1
(integer) 0 #不存在
127.0.0.1:6379>move name 1 #移除某个key 1表示当前数据库
(integer) 1
127.0.0.1:6379>expire name 10 #设置过期时间10秒
(integer) 1
127.0.0.1:6379>ttl name #查看剩余过期时间
127.0.0.1:6379>type name #查看当前key类型
string
String类型(字符串)
127.0.0.1:6379>set key1 v1
OK
127.0.0.1:6379>get key1
"v1"
127.0.0.1:6379>keys *
1)"key1"
127.0.0.1:6379>exists key1
(integer) 1
127.0.0.1:6379>append key1 "hello" #追加"hello",如果当前key不存在相当于新增
(integer) 7 #返回长度
127.0.0.1:6379>get key1
"v1hello"
127.0.0.1:6379>strlen key1 #获取当前key长度
(integer) 17
############################################################################
127.0.0.1:6379>set views 0
OK
127.0.0.1:6379>get views
"0"
127.0.0.1:6379>incr views #加1,相当于java中的i++,使用场景网站浏览量,文章阅读量...
(integer) "1"
127.0.0.1:6379>incr views
(integer) "2"
127.0.0.1:6379>get views
"2"
127.0.0.1:6379>decr views #减1
(integer) "1"
127.0.0.1:6379>decr views
(integer) "0"
127.0.0.1:6379>decr views
(integer) "-1"
127.0.0.1:6379>incrby views 10 #设置自增步长为10
(integer) "9"
127.0.0.1:6379>decrby views 5 #设置自减步长为5
(integer) "4"
#############################################################################
字符串范围 range
127.0.0.1:6379>set key1 "itstom,saygoodbye"
OK
127.0.0.1:6379>getrange key1 0 3 #截取字符串
"itst"
127.0.0.1:6379>getrange key1 0 -1 #查看全部
"itstom,saygoodbye"
127.0.0.1:6379>setrange key1 1 xx #替换指定位置字符串,从下标为0开始,替换两个
"ixxtom,saygoodbye"
##############################################################################
#setex(set with expire) 设置过期时间
#setnx(set if not exits) 不存在再设置,存在的话设置失败(在分布式锁中经常使用)
127.0.0.1:6379>set key3 30 hello #设置key3的值为hello,30秒后过期
OK
127.0.0.1:6379>ttl key3
(integer) 27
127.0.0.1:6379>setnx mykey redis #如果不存在,就会创建mykey
(integer) 1
127.0.0.1:6379>setnx mykey tomcat #如果mykey存在创建失败
(integer) 0
127.0.0.1:6379>get mykey
redis
##################################################################################
#批量设置
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
127.0.0.1:6379> keys *
1)k1
2)k2
3)k3
127.0.0.1:6379>mget k1 k2 k3 #同时获取多个值
1)v1
2)v2
3)v3
127.0.0.1:6379>msetnx k1 v1 k4 v4 #要么一起成功,要么一起失败
(integer) 0
##################################################################################
#getset 先get然后set
(empty array)
127.0.0.1:6379> getset key1 hello #如果不存在就返回nil,并创建
(nil)
127.0.0.1:6379> getset key1 hello
"hello"
127.0.0.1:6379> get key1
"hello"
127.0.0.1:6379>
String类型的使用场景:value除了可以是字符串,也可以是数字
- 计数器
- 统计多单位的数量
- 粉丝数量
- 对象缓存存储