REDIS分析与思考

一. Redis的历史

1. 什么是nosql

    nosql=not only sql,不仅仅是sql,是区别于关系型数据库的一种。

    关系型数据库:具有行列组成的表格样式的数据库

    nosql数据库:数据的存储不需要指定类型、不需要过多的操作就可以横向扩展,

2. nosql特点:

  • 方便扩展(数据之间KV存储,没有关系,很好扩展)
  • 大数据量高性能(官方测试一秒钟读取11万,写8万次)
  • 数据类型是多样的,随取随用,并可以设置过期
  • 关系型数据库RDBMS和nosql数据库区别

传统的RDBMS:

- 结构化组织(行列组成的表关系)

- 有单独的执行操作语法

- 严格的一致性

- 事务控制

nosql数据库:

- 没有固定的查询语句

- 存储形式多样:键值对存储、列存储、文档存储、图形数据库

- 保证最终一致性

- 高性能、高可用、高扩展

- CAP定理和BASE  实现了异地多活。

3. nosql 的四大分类

①KV键值对

   通过KV的形式完成存储,像Redis的KV键值对

②文档型数据库

  最经典的就是MongoDB,他是一个基于分布式文件存储的数据库,主要用来处理大量的文件

  他是介于关系型数据库和非关系型数据库之间,并且是非关系型数据库中最接近关系型数据库的数据库.

③列数据库

  Hbase、分布式文件系统等以列进行存储的数据库

④图形数据库(关系拓扑图)

一般用来存储朋友圈社交网络、广告产品推荐等。

------图片来自网络 

4. 什么是Redis、Redis能做什么?

  Redis(Remote Dictionary Server ),即远程字典服务。是支持网络、可基于内存亦可持久化的日志型、Key-Value数据库。

Redis能做什么:

  • 可以作为内存存储,并提供持久化功能(内存不持久化则断电即失)
  • 效率高,可以用于告诉缓存
  • 发布订阅系统
  • 地图信息分析
  • 计数器计时器控制

 

二.Redis安装以及基本知识

1. Linux安装Redis

  ①下载Redis安装包:https://redis.io/

  ②解压安装包至/usr/develop/redis目录中

  ③解压安装包,tar -zxvf redis-5.0.8.tar.gz

  ④安装Redis编译环境: yun install -y gcc-c++

  ⑤进入到Redis的路径,make执行编译后make install执行安装。

  ⑥安装完成后默认安装目录是在/usr/local/bin下,将安装包中的配置文件rdis.conf复制到/usr/local/bin/wconf下:

 cp /usr/develop/redis/redis.conf /usr/local/bin/wconf

  ⑦修改配置文件:

            默认是非后台启动,修改为后台启动:daemonize yes

            默认是本机访问,修改为任意终端访问:bind 0.0.0.0

            默认是无密码访问,添加Redis访问密码:取消第502行的注释,并修改密码为root

                              # use a very strong password otherwise it will be very easy to break.
                              #         requirepass root

                              # Command renaming.

  ⑧启动Redis。指定配置文件方式启动:在/usr/local/bin路径下:./redis-server wconf/redis.conf,查询到Redis进程号即代表启动成功了。

  ⑨启动客户端测试ping为pong即代表服务启动成功

2.  redis-benchmark压力测试工具的使用

    redis-benchmark是Redis官方的压力测试工具,通过命令来进行测试。

   简单测试1000个并发下请求10W个请求,每次请求100字节的压力测试命令:

   redis-benchmark -h localhost -p 6379 -c 1000 -n 100000 -d 100

其他常用指令可自行百度

3. Redis的基本知识 

    ---redis默认有16个库,在配置文件database 16 中表示

    ---Redis是单线程

             Redis是基于内存操作。CPU不是Redis的性能瓶颈(多线程是CPU),Redis的瓶颈是根据机器的内存和网络带宽。所以使用单线程来实现。

            为什么单线程还这么快呢:

                 ①多线程不一定比单线程效率高,多线程会涉及到CPU的上下文切换,这是一个耗时的操作。Redis是完全放在内存操作的,读写都是在同一个CPU上操作的。同时也不存在并发时的加锁释放锁的问题。当访问量多时,单线程能够节省多线程CPU的上下文切换。所以说单线程是最快。

                ②才用多路IO复用模型,属于非阻塞IO

4. redis的常用命令

不会的命令可以查看官网

* select 6 #切换数据库

* dbsize  #查看数据库大小

         

三. Redis的五大数据类型

1. redis-key的命令

*  keys *  # 查看所有key

*  flushdb  #清空当前库   flushall  #清空所有数据库

* exists key  #查询某个key是否存在,1存在/0不存在

* move key 1 #移除key值,1代表当前库

* expire key 30   #设置key值30秒过期

* ttl key   #查询key的剩余过期时间 单位是S

* type  key   #查看key的数据类型

2. String(字符串)

字符串类型的KV数据,使用场景:value一般是字符串或者数字。可以用来做计数器、统计数量等

* set key hello  #设置值

* get key   #获取值

* mset k1 v1 k2 v2    # 批量设置kv值,同时set了k1、k2

mget k1 k2    # 批量获取值,同时获取k1、k2的值

* append key "append"  # 给key值后面追加字符串append,如果key值不存在,则会新创建

* strlen key  #获取字符串的长度

* incr key  #将key值+1,可以用来记录网站的浏览量 每次执行就会+1,操作非数字的key会报错

* incrby key 10  #将key值每次+10,即可以设置步长

* decr key  #将key值-1。

* decrby key 10  #将key值每次-10

* getrange key 0 3    #截取字符串,相当于java中substring, getrange key start end  ,从0开始,本例为从0截取到3---->[0,3]字符

       GETRANGE key1 4 -1   #从4截取到最后,-1为最后。

* setrange key 1 xx  #替换,把key中从第1个开始,替换成xx。指定位置的替换。可替换一个或多个

* setex(set with expire)     #设置一个key值,并设置过期时间  : setex key 30 "hello", 设置key值为hello并30秒过去

setnx(set if no exist)     #设置一个key值,当他不存在时,如果该key值已经存在,则会设置失败,直接set如果存在则会覆盖

           setnx key "hello"   如果存在返回0,set失败,如果不存在返回1,set成功。 在分布式锁中常常会被使用。

* msetnx k1 v1 k4 v4        #setnx是一个原子性操作,如果k1已经存在了,k4不存在,同样k4也不会添加成功。

   技巧:通过巧妙的key值,方便工作 例如,设置ID为1的用户登录次数+1   set user:1:login 0   以后再每次给该用户+1时,可以动态的根据ID来给该value值进行操作,不用直接存储user对象解析后再+1了。

* getset key hello   # 如果不存在值,返回null,并设置新值,如果存在,返回原来值,并设置新的值。可用来更新操作。

3. list(列表)

在Redis里,可以把list作为栈、队列、阻塞队列来使用。list中的值是可以重复的。

所有list命令都是用l开头的。

list的存储顺序是: lpush list one, lpush list two, lpush list three。则获取第0个位three,获取第1个位two,获取第2个为one.顺序为先进后出。倒着来的。

list 实际上是一个链表,存在node,node 有before和after, 在left和right都可以进行插入值。

在两边执行操作,效率最高,但是在中间元素操作,效率会低一点。

* lpush list one  lpush list two   lpush list three      #将一个值或者多个值放入列表的头部,push的顺序是往左边(头部)放,存放顺序是从右至左

* lrange list 0 -1   #获取全部的list值,   lrange  list  0 1 ,获取0-1的值, 顺序是从左到右取值。

* rpush list four   #将一个多个值放在列表的尾部。push的顺序是往右边(尾部)放,存放顺序为从左往右。

* lpop list    #将list的值最左边的值移除,并返回该值。即第一个

* rpop list   #将list的最右边的值移除,并返回该值。即最后一个

lrem list 2 one    #从左到右移除list中指定的两个one值,并指定移除个数

* lindex list 1   # 通过下标获取list中的某个值。从0开始

* LLEN list   #获取list的长度

* ltrim list 1 2     #将list中的1-2位置上的值进行截取,list中其余的就没有了。通过下标截取指定长度。

* rpoplpush list otherList    #移动操作。将list中的最后一个(rpop)移动到(lpush) otherList中去,otherlist中就是list被移除的最后一个值

* lset  list 0 value    #将列表中已经存在的指定下标的值更新为另一个值,如果list不存在/或者下标越界,则报错。

* linsert list before/after "hello" "other"   #在list中指定的元素前/后  插入一个指定的value值。hello是list中存在的指定元素, other 是需要插入的值,此时执行结果就是 list中多了一个元素,在hello的前面

 

 

 

 

 

 

 

 

 

三. Redis配置以及持久化

四. Redis事务、订阅发布

五. Redis的主从复制以及哨兵模式

六. 缓存穿透雪崩解决方案

七. API使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章