美文网首页
Redis 学习笔记(1)

Redis 学习笔记(1)

作者: SYFHEHE | 来源:发表于2020-11-18 22:49 被阅读0次

    1 NoSQL概述:

    1.1 为什么要用Nosql

    1.1.1 单机年代

    数据量太大,一台机器放不下
    数据的索引(B+tree),一个服务器承受不了
    数据库访问量太大(读写混合)

    1.1.2 Memcached + 垂直同步 + 读写分离

    image.png

    发展过程:
    优化数据结构和索引-->文件缓存(IO)-->Memcached(当时最热门的技术)

    1.1.3 分库分表 + 水平拆分 + MySQL集群

    早些年MyISAM:表锁,查用户,会把整个表锁住
    InnoDb:行锁
    分库分表来解决写的压力

    1.1.4 NoSQL

    图形 BSON(二进制的JSON)
    数据量大,文件图片很多,数据库的表很大。效率低。

    目前一个基本互联网项目的基本架构


    image.png

    1.1.5 为啥要用NoSQL

    用户的个人信息,,社交网络,地理位置。用户自己产生的数据,用户日志呈爆发式增长,NoSQL可以很好的处理以上情况。

    1.2 什么是Nosql

    NoSQL(Not Only SQL),意思是"不仅仅是 SQL",指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称。

    NoSQL 用于超大规模数据的存储。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。


    image.png

    1.3 NoSQL的四大分类

    image.png
    1. KV键值对:Redis
    2. 文档数据类型:
    • MongoDB
      • MongoDB是基于分布式文件存储的数据库,主要用来处理大量的文档
      • MongoDB是介于关系型数据库和菲关系新数据库之间的数据库。
    1. 列存储数据库:
    • HBase
    • 分布式文件系统
    1. 图关系数据库:
    • Neo4J, InfoGrid, Infinite Graph

    2. Redis入门:

    Redis是什么:Remote Dictionary Server,远程字典服务,Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

    2.1 windows Redis 安装

    这里我选择的是x64-3.2.100,下载的时候下载msi(不要下载zip的压缩包)

    如果你是和我一样通过msi文件的安装,你可以在计算机管理→服务与应用程序→服务 看到Redis正在运行

    image

    你也可以将它停止,(不停止会出现错误代码为18012的错误,表示本机端口6379被占用)

    然后在cmd窗口进入Redis的安装路径的根目录 (C:\Program Files\Redis\)

    输入命令redis-server.exe redis.windows.conf,出现下图证明Redis服务启动成功

    image

    2.1.1 使用redis客户端来连接redis server

    image.png

    2.2 Linux Redis 安装

    2020最新Linux系统发行版ContOS7演示安装Redis

    2.3 Benchmark 测试 redis 性能

    ./redis-benchmark -h localhost -p 6379 -c 100 -n 100000


    image.png

    2.4 Redis 基本知识

    Redis 启动server:
    cd /usr/local/bin
    ./redis-server conf/redis.conf
    
    Redis启动客户端:
    [root@localhost bin] ./redis-cli -p 6379
    127.0.0.1:6379> ping
    PONG
    127.0.0.1:6379> 
    
    选择数据库和清空数据库
    • flushdb 清空当前数据库
    • flushall 清空所有16个数据库
    127.0.0.1:6379> select 3
    OK
    127.0.0.1:6379[3]> DBSIZE
    (integer) 0
    
    127.0.0.1:6379> keys *
    1) "myhash:{tag}"
    2) "name"
    3) "key:{tag}:__rand_int__"
    4) "mylist:{tag}"
    5) "counter:{tag}:__rand_int__"
    127.0.0.1:6379> flushdb
    OK
    127.0.0.1:6379> DBSIZE
    (integer) 0
    127.0.0.1:6379> keys *
    (empty array)
    
    
    Redis是单线程的!

    Redis是基于内存操作的,CPU不是redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽决定的
    为什么是单线程还这么快。

    Redis是C语言写的,每秒的QPS为100000+,不必Memecache差。
    核心:redis是将所有的数据全部放在内存里,所以说使用单线程去操作效率就是最高的,多线程的CPU是上下文会切换,耗时的操作,对内存系统来说,没有上下文切换的效率就是最高的,多次读写都是在一个CPU上的,这就是内存系统的最佳方案。

    3 Redis 数据类型:

    3.1 String类型

    • key操作:
    127.0.0.1:6379> select 1
    OK
    127.0.0.1:6379[1]> set name 123
    OK
    127.0.0.1:6379[1]> set age 12
    OK
    127.0.0.1:6379[1]> keys *
    1) "age"
    2) "name"
    127.0.0.1:6379[1]> EXISTS name
    (integer) 1
    127.0.0.1:6379[1]> EXISTS name1
    (integer) 0
    127.0.0.1:6379[1]> move name 2
    (integer) 1
    127.0.0.1:6379[1]> keys
    (error) ERR wrong number of arguments for 'keys' command
    127.0.0.1:6379[1]> keys *
    1) "age"
    
    • 设置过期时间
    127.0.0.1:6379[1]> keys *
    1) "age"
    2) "name"
    127.0.0.1:6379[1]> EXPIRE name 12
    (integer) 1
    127.0.0.1:6379[1]> ttl name
    (integer) 8
    127.0.0.1:6379[1]> ttl name
    (integer) 6
    127.0.0.1:6379[1]> type age  #查看类型 
    string
    
    
    • 计算长度
    [root@VM-0-6-centos bin]# ./redis-cli -p 6379
    127.0.0.1:6379> select 1
    OK
    127.0.0.1:6379[1]> keys *
    1) "age"
    127.0.0.1:6379[1]> append age index #append value, key不存在就set key
    (integer) 7
    127.0.0.1:6379[1]> keys *
    1) "age"
    127.0.0.1:6379[1]> get age
    "12index"
    127.0.0.1:6379[1]> STRLEN age #计算长度
    
    • 增加 减少 数值
    [root@VM-0-6-centos bin]# ./redis-cli -p 6379
    127.0.0.1:6379> set age 1
    OK
    127.0.0.1:6379> incr age
    \(integer) 2
    127.0.0.1:6379> incr age
    (integer) 3
    127.0.0.1:6379> decr age
    (integer) 2
    127.0.0.1:6379[1]> INCRBY name 10
    (integer) 10
    127.0.0.1:6379[1]> INCRBY name 10
    (integer) 20
    
    • 字符串截取和替换
    127.0.0.1:6379> set name "hello.syf niubi"
    OK
    127.0.0.1:6379> get name
    "hello.syf niubi"
    127.0.0.1:6379> GETRANGE name 1 12
    "ello.syf niu"
    127.0.0.1:6379> GETRANGE name 0 -1 # 获取整个字符串
    "hello.syf niubi"
    127.0.0.1:6379> SETRANGE name 1 123456
    (integer) 15
    127.0.0.1:6379> get name
    "h123456yf niubi"
    
    • setex : 将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX 命令将覆写旧值。
    • setnx : 只在键 key 不存在的情况下, 将键 key 的值设置为 value 。若键 key 已经存在, 则 SETNX 命令不做任何动作。在分布式锁中将常常使用。
    127.0.0.1:6379> set key3 60
    OK
    127.0.0.1:6379> setex key3 30 hello
    OK
    127.0.0.1:6379> get key3
    "hello"
    127.0.0.1:6379> setnx mykey "redis"
    (integer) 1
    127.0.0.1:6379> get mykey
    "redis"
    127.0.0.1:6379> setnx mykey "mongoDB"  #只在键 key 不存在的情况下, 将键 key 的值设置为 value 。若键 key 已经存在, 则 SETNX 命令不做任何动作。
    (integer) 0
    127.0.0.1:6379> get mykey
    "redis"
    
    • mset
    • msetnx
    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
    OK
    127.0.0.1:6379> keys *
    1) "k2"
    2) "k3"
    3) "name"
    4) "mykey"
    5) "k1"
    127.0.0.1:6379> msetnx k1 v1 k4 v4 # 原子性 要么一起成功 要么一起失败
    (integer) 0
    127.0.0.1:6379> keys *
    1) "k2"
    2) "k3"
    3) "name"
    4) "mykey"
    

    保存对象:

    Redis Getset 命令:Redis Getset 命令用于设置指定 key 的值,并返回 key 的旧值。

    3.2 list(列表)

    • 基本操作
    127.0.0.1:6379> LPUSH list one #List里面塞值
    (integer) 1
    127.0.0.1:6379> LPUSH list two
    (integer) 2
    127.0.0.1:6379> LRANGE list 0 -1
    1) "two"
    2) "one"
    127.0.0.1:6379> lpop list #移除列表的第一个元素
    "two"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "one"
    127.0.0.1:6379> LPUSH list two
    (integer) 2
    127.0.0.1:6379> rpop list #移除列表的最后个元素
    "one"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "two"
    
    • lindex 通过下标获取某个值
    • llen 返回列表的长度
    • LREM key count value: 根据参数 count 的值,移除列表中与参数 value 相等的元素。
    127.0.0.1:6379> lindex list 0
    127.0.0.1:6379> llen list
    (integer) 1
    redis> LREM greet 2 morning     # 移除从表头到表尾,最先发现的两个 morning
    (integer) 2                     # 两个元素被移除
    
    • rpoplpush: 移除列表的最后一个元素,并将它添加到另一个list的最左边
    127.0.0.1:6379> rpush list a
    (integer) 2
    127.0.0.1:6379> rpush list b
    (integer) 3
    127.0.0.1:6379> rpush list c
    (integer) 4
    127.0.0.1:6379> rpoplpush list mylist
    
    • LSET key index value
      将列表 key 下标为 index 的元素的值设置为 value 。
      当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,返回一个错误。

    • LINSERT key BEFORE|AFTER pivot value
      将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
      当 pivot 不存在于列表 key 时,不执行任何操作。
      当 key 不存在时, key 被视为空列表,不执行任何操作。
      如果 key 不是列表类型,返回一个错误。

    总结

    • 消息队列:Lpush Rpop
    • 栈:Lpush Lpop

    3.3 Set对象

    3.2.1 基本操作

    127.0.0.1:6379> sadd myset "hello" # 添加set成员
    (integer) 1
    127.0.0.1:6379> sadd myset "syf"
    (integer) 1
    127.0.0.1:6379> sadd myset "xule"
    (integer) 1
    127.0.0.1:6379> smembers myset
    1) "xule"
    2) "hello"
    3) "syf"
    127.0.0.1:6379> sadd myset "xule"
    (integer) 0
    127.0.0.1:6379> smembers myset # 查看指定set的所有值
    1) "xule"
    2) "hello"
    3) "syf"
    127.0.0.1:6379> sismember myset syf # 查看是否包含某个元素
    (integer) 1
    127.0.0.1:6379> sismember myset syf1
    (integer) 0
    127.0.0.1:6379> scard myset # 获取个数
    127.0.0.1:6379> srem myset xule # 移除某一个元素
    127.0.0.1:6379> srandmember myset # 随机抽选出一个元素
    127.0.0.1:6379> srandmember myset 2 # 随机抽选出指定个数的个元素
    127.0.0.1:6379> spop myset 1 # 随机抽移除指定个数的个元素
    127.0.0.1:6379> smove myset myset2 haha # 移动到另外一个集合
    (integer) 1
    127.0.0.1:6379> smembers myset2
    1) "haha"
    

    3.2.2 数字集合类

    • 差集
    • 交集
    • 并集
    127.0.0.1:6379> sadd key1 a
    (integer) 1
    127.0.0.1:6379> sadd key1 b
    (integer) 1
    127.0.0.1:6379> sadd key1 c
    (integer) 1
    127.0.0.1:6379> sadd key2 c
    (integer) 1
    127.0.0.1:6379> sadd key2 b
    (integer) 1
    127.0.0.1:6379> sadd key2 a
    (integer) 1
    127.0.0.1:6379> sadd key2 d
    (integer) 1
    127.0.0.1:6379> sadd key1 e
    (integer) 1
    127.0.0.1:6379> sdiff key1 key2 # Redis Sdiff 命令返回第一个集合与其他集合之间的差异,也可以认为说第一个集合中独有的元素。
    1) "e"
    127.0.0.1:6379> sinter key1 key2
    1) "c"
    2) "a"
    3) "b"
    127.0.0.1:6379> sunion key1 key2
    1) "c"
    2) "a"
    3) "e"
    4) "b"
    5) "d"
    127.0.0.1:6379> sdiff key1 key2
    1) "e"
    127.0.0.1:6379> smembers key1
    1) "c"
    2) "a"
    3) "e"
    4) "b"
    127.0.0.1:6379> smembers key2
    1) "a"
    2) "c"
    3) "b"
    
    

    3.4 Hash对象

    127.0.0.1:6379> hset myhash key1 value1
    (integer) 1
    127.0.0.1:6379> hget myhash key1
    "value1"
    127.0.0.1:6379> hset myhash key1 value2
    (integer) 0
    127.0.0.1:6379> hget myhash key1
    "value2"
    127.0.0.1:6379> hgetall myhash
    1) "key1"
    2) "value2"
    127.0.0.1:6379> hdel myhash key1
    (integer) 1
    127.0.0.1:6379> hgetall myhash
    (empty array)
    127.0.0.1:6379> hlen myhash1 #获取长度
    1
    127.0.0.1:6379> hset myhash key1 v1 key2 v2 key3 v3 #多个值同时set
    (integer) 3
    127.0.0.1:6379> hgetall myhash
    1) "key1"
    2) "v1"
    3) "key2"
    4) "v2"
    5) "key3"
    6) "v3"
    127.0.0.1:6379> hlen myhash 
    (integer) 3
    127.0.0.1:6379> hexists myhash key2 #判断指定字段是否存在
    127.0.0.1:6379> hvals myhash
    1) "v1"
    2) "v2"
    3) "v3"
    

    3.5 特殊数据类型

    https://blog.csdn.net/qq_35423154/article/details/109674794

    相关文章

      网友评论

          本文标题:Redis 学习笔记(1)

          本文链接:https://www.haomeiwen.com/subject/qstdbktx.html