Redis 学习笔记(1)

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))