入门概述
为什么用nosql
- 单机mysql的美好年代
- memcached(缓存)+mysql+垂直拆分
- mysql主从读写分离
- 分表分库+水平拆分+mysql集群
- mysql的扩展性瓶颈
- 今天时什么样子
- 为什么用nosql
redis是什么
Redis:REmote DIctionary Server(远程字典服务器)
是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的Nosql数据库,是当前最热门的Nosql数据库之一,也被人们称为数据库结构服务器
redis的三个特点
- redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
- redis支持数据的备份,即master-slve模式的数据备份
reids能干嘛
- 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- 取最新n个数据的操作,如:可以将最新的10条评论的ID放在redis的List集合里面
- 模拟类似于HttpSession这种需要设定过期时间的功能
- 发布,订阅消息系统
- 定时器,计数器
去哪里下
http://www.redis.cn/
redis.io
怎么玩
- 数据类型,基本操作和配置
- 持久化和复制,RDB/AOF
- 事务的控制
- 复制
- 。。。
由于企业里面做redis开发,99%都是linux版的运用和安装,几乎不会涉及到windows版
我的安装(windows)
下载地址:https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100
解压
在系统变量的path中添加redis解压后的目录: E: edis
设置密码:redis.windows-service.conf(444行)
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
# requirepass foobared
requirepass 123456
# Command renaming.
注册服务:用dos窗口静茹redis目录 执行redis-server.exe --service-install redis.windows.conf --loglevel verbose,然后查看“服务”。
启动:启动服务后,命令行输入redis-cli.exe -h 127.0.0.1 -p 6379,连接redis
C:Users13749>redis-cli.exe -h 127.0.0.1 -p 6379
127.0.0.1:6379> set redis "hello redis"
OK
127.0.0.1:6379> get redis
"hello redis"
127.0.0.1:6379>
win10启动redis报错:[5308] 14 Sep 22:39:50.903 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
1. redis-cli.exe
2. shutdown
3. exit
4. redis-server.exe redis.windows.conf
reids数据类型
String(字符串)
- String 是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个valuse
- String类型是二进制安全的,意思是redis的String可以包含任何数据,比如jpg图片或者序列化的对象
- String类型是redis最基本的数据类型,一个redis中字符串value最多可以是512M
Hash(哈希,类似java里的map)
- redis hash是一个键值对集合
- redis hash是一个String类型的field和value的映射表,hash特别适用于存储对象
- 类似java里面的Map<String,Object>
List(列表)
- redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素导致表的头部(左边)或者尾部(右边).
- 它的底层实际是个链表
Set(集合)
- redis的set是String类型的无序集合,它是通过HashTable实现的
- 无序无重复
Zset(sorted set:有序集合)
- redis zset和set一样也是String类型元素的集合,且不允许重复的成员。
- 不同的是每个元素都会关联一个double类型的分数
- redis正是通过分数来为集合的成员从小到大的排序,zset的成员是唯一的,但分数(score)却可以重复
redis常见数据类型操作命令
键(key)
keys * 查看
127.0.0.1:6379> keys *
1) "redis"
2) "a"
set key value 设置值
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
exists key 判断是否存在 1存在 0 不存在
127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k11
(integer) 0
move key 哪个库 当前库就没有了,被移除了
127.0.0.1:6379> move k2 2
(integer) 1
127.0.0.1:6379> select 2 进入到哪个库
OK
127.0.0.1:6379[2]> keys *
1) "k2"
ttl key 查看还有多少秒过期 -1表示永不过期,-2表示已过期
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "redis"
2) "a"
3) "k3"
4) "k1"
127.0.0.1:6379> ttl k1
(integer) -1
127.0.0.1:6379>
expire key 时间秒 为给定的key设置过期时间(已过期生命周期终结,终结就要移除内存系统)
127.0.0.1:6379> expire k1 20
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 15
127.0.0.1:6379> ttl k1
(integer) 9
127.0.0.1:6379> ttl k1
(integer) -2
127.0.0.1:6379> keys *
1) "redis"
2) "a"
3) "k3"
type key 查看你的key是什么类型
127.0.0.1:6379> type redis
string
如果存在,再设置就覆盖
127.0.0.1:6379> get redis
"hello redis"
127.0.0.1:6379> set redis hhh
OK
127.0.0.1:6379> get redis
"hhh"
127.0.0.1:6379>
del key key存在则删除
127.0.0.1:6379> keys *
1) "redis"
2) "a"
3) "k3"
127.0.0.1:6379> del a
(integer) 1
127.0.0.1:6379> keys *
1) "redis"
2) "k3"
字符串(String)
单值单value
append key 需要增加的
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> append k1 123
(integer) 5
127.0.0.1:6379> get k1
"v1123"
strlen key 查看长度
127.0.0.1:6379> get k1
"v1123"
127.0.0.1:6379> strlen k1
(integer) 5
incr key 自增1
127.0.0.1:6379> set k1 1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> incr k1
(integer) 2
127.0.0.1:6379> incr k1
(integer) 3
127.0.0.1:6379> incr k1
(integer) 4
decr key 自减1
127.0.0.1:6379> decr k1
(integer) 3
127.0.0.1:6379> decr k1
(integer) 2
127.0.0.1:6379> decr k1
(integer) 1
incrby key 数字 加多少
127.0.0.1:6379> get k1
"1"
127.0.0.1:6379> incrby k1 3
(integer) 4
127.0.0.1:6379> incrby k1 3
(integer) 7
decrby key 数字 减多少
127.0.0.1:6379> decrby k1 2
(integer) 5
127.0.0.1:6379> decrby k1 2
(integer) 3
getrange 获取指定区间范围内的值,类似between...and的关系
从零到负一表示全部
127.0.0.1:6379> get k1
"abc12345"
127.0.0.1:6379> GETRANGE k1 0 -1
"abc12345"
127.0.0.1:6379> GETRANGE k1 0 3
"abc1"
setrange设置指定区间范围内的值,格式是setrange key值 具体值
127.0.0.1:6379> get k1
"abc12345"
127.0.0.1:6379> SETRANGE k1 0 xxx
(integer) 8
127.0.0.1:6379> get k1
"xxx12345"
SETEX key 时间 value 设置一个会过期的
127.0.0.1:6379> SETEX k4 10 v4
OK
127.0.0.1:6379> ttl k4
(integer) 5
127.0.0.1:6379> ttl k4
(integer) 0
127.0.0.1:6379> get t4
(nil)
setnx key value (set if not exist)当key不存在的时候才设置值 不覆盖
127.0.0.1:6379> get k1
"xxx12345"
127.0.0.1:6379> setnx k1 aaa
(integer) 0
127.0.0.1:6379> get k1
"xxx12345"
127.0.0.1:6379> setnx k11 v11
(integer) 1
mset 一次性设置多个值
mget 一次性取多个值
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
msetnx 一次性设置多个值 同时成功同时失败
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k11"
4) "k1"
127.0.0.1:6379> msetnx k2 22 k3 33 k4 44
(integer) 0
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k11"
4) "k1"
列表(List)
单值多value
FLUSHdb 清除所有
lpush 正进反出
lrange 查询范围
127.0.0.1:6379> lpush list01 1 2 3 4 5
(integer) 5
127.0.0.1:6379> lrange list01 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
rpush 正进正出
127.0.0.1:6379> rpush list02 1 2 3 4 5
(integer) 5
127.0.0.1:6379> lrange list02 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
lpop 栈顶出
127.0.0.1:6379> LRANGE list01 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> lpop list01
"5"
127.0.0.1:6379> LRANGE list01 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379>
rpop
127.0.0.1:6379> rpop list01
"1"
127.0.0.1:6379> LRANGE list01 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379>
lindex 按照索引下标获得元素(从上到下),下标0开始
127.0.0.1:6379> LRANGE list01 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> lindex list01 3
(nil)
127.0.0.1:6379> lindex list01 2
"2"
llen 获取长度
127.0.0.1:6379> LRANGE list01 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> llen list01
(integer) 3
lrem key 几个 值 删除n个value
127.0.0.1:6379> rpush list03 1 1 1 2 3 3 3 3 5 6
(integer) 10
127.0.0.1:6379> lrem list03 2 1
(integer) 2
127.0.0.1:6379> lrange list03 0 -1
1) "1"
2) "2"
3) "3"
4) "3"
5) "3"
6) "3"
7) "5"
8) "6"
ltrim key 卡死hiindex 结束index 截取指定范围的值后再赋值给key
127.0.0.1:6379> rpush list01 1 2 3 4 5 6
(integer) 6
127.0.0.1:6379> lrange list01 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> ltrim list01 0 3
OK
127.0.0.1:6379> lrange list01 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
lrange key index value 设置值
127.0.0.1:6379> lrange list01 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> lset list01 0 0
OK
127.0.0.1:6379> leange list01
(error) ERR unknown command 'leange'
127.0.0.1:6379> lrange list01 0 -1
1) "0"
2) "2"
3) "3"
linsert key before/after 值1 值2
127.0.0.1:6379> lrange list01 0 -1
1) "0"
2) "2"
3) "3"
127.0.0.1:6379> linsert list01 before 9
(error) ERR wrong number of arguments for 'linsert' command
127.0.0.1:6379> linsert list01 before 2 java
(integer) 4
127.0.0.1:6379> lrange list01 0 -1
1) "0"
2) "java"
3) "2"
4) "3"
性能总结
- 它是一个字符串链表,left right都可以插入添加
- 如果键不存在,创建新的链表
- 如果键已存在,对应的键也就消失了
- 链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了
集合(Set)
单值多value
sadd 加
smembers 查全部
127.0.0.1:6379> sadd set01 1 1 2 3 2 3 4
(integer) 4
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "3"
4) "4"
sismember 查询是否存在
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sismember set01 1
(integer) 1
127.0.0.1:6379> sismember set01 5
(integer) 0
scard 查个数
127.0.0.1:6379> scard set01
(integer) 4
srem 删除集合中的元素
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> srem set01 3
(integer) 1
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "4"
srandmember 随机出几个数
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "4"
4) "7"
5) "8"
6) "9"
7) "11"
8) "22"
9) "66"
127.0.0.1:6379> srandmember set01 3
1) "2"
2) "8"
3) "66"
spop 随机出栈
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "4"
4) "7"
5) "8"
6) "9"
7) "11"
8) "22"
9) "66"
127.0.0.1:6379> spop set01 2
1) "11"
2) "4"
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "7"
4) "8"
5) "9"
6) "22"
7) "66"
smove key1 key2 在key1里取某个值 作用是将key1里的某个值赋给key2(key1里的该值移除)
127.0.0.1:6379> smove set01 set02 66
(integer) 1
127.0.0.1:6379> smembers set02
1) "y"
2) "x"
3) "z"
4) "66"
127.0.0.1:6379> smembers set01
1) "1"
2) "2"
3) "7"
4) "8"
5) "9"
6) "22"
哈希(Hash)
KV模式不变,但V是一个键值对
127.0.0.1:6379> hset user id 11
(integer) 1
127.0.0.1:6379> hget user id
"11"
hmset
127.0.0.1:6379> hmset customer id 1 name ls age 22
OK
hmget
127.0.0.1:6379> hmget customer id name age
1) "1"
2) "ls"
3) "22"
hgetall
127.0.0.1:6379> hgetall customer
1) "id"
2) "1"
3) "name"
4) "ls"
5) "age"
6) "22"
hdel
127.0.0.1:6379> hgetall customer
1) "id"
2) "1"
3) "name"
4) "ls"
5) "age"
6) "22"
127.0.0.1:6379> hdel customer id
(integer) 1
hgetall
127.0.0.1:6379> hgetall customer
1) "name"
2) "ls"
3) "age"
4) "22"
hlen
127.0.0.1:6379> hlen customer
(integer) 2
hexists
127.0.0.1:6379> hexists customer age
(integer) 1
127.0.0.1:6379> hexists customer email
(integer) 0
hkeys
127.0.0.1:6379> hkeys customer
1) "name"
2) "age"
hvals
127.0.0.1:6379> hvals customer
1) "ls"
2) "22"
hincrby
127.0.0.1:6379> hvals customer
1) "ls"
2) "22"
127.0.0.1:6379> hincrby customer age 2
(integer) 24
127.0.0.1:6379> hincrby customer age 2
(integer) 26
hincrbyfloat
127.0.0.1:6379> hset customer score 90.5
(integer) 1
127.0.0.1:6379> hincrbyfloat customer score 0.5
"91"
127.0.0.1:6379> hincrbyfloat customer score 0.5
"91.5"
127.0.0.1:6379> hsetnx customer age 20
(integer) 0
127.0.0.1:6379> hsetnx customer email 123@qq.com
(integer) 1
有序集合(Zset)
多说一句:在set基础上,加一个score值。之前set是k1 v1 v2 v3,现在zset是k1 score1 v1 score2 v2
zadd 增加
127.0.0.1:6379> zadd zset01 60 v1 70 v2 80 v3 90 v4 100 v5
(integer) 5
zrange 查询
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zrange zset01 0 -1 withscores
1) "v1"
2) "60"
3) "v2"
4) "70"
5) "v3"
6) "80"
7) "v4"
8) "90"
9) "v5"
10) "100"
zrangebyscore 闭区间
127.0.0.1:6379> zrangebyscore zset01 60 90
1) "v1"
2) "v2"
3) "v3"
4) "v4"
zrangebyscore (不包含
127.0.0.1:6379> zrangebyscore zset01 60 (90
1) "v1"
2) "v2"
3) "v3"
zrangebyscore 从哪个下标开始截取几个
127.0.0.1:6379> zrangebyscore zset01 60 90
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> zrangebyscore zset01 60 90 limit 2 2
1) "v3"
2) "v4"
zrem 移除
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zrem zset01 v5
(integer) 1
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
zcard 统计个数
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> zcard zset01
(integer) 4
zcount 统计一个范围的个数
127.0.0.1:6379> zrange zset01 0 -1 withscores
1) "v1"
2) "60"
3) "v2"
4) "70"
5) "v3"
6) "80"
7) "v4"
8) "90"
127.0.0.1:6379> zcount zset01 60 80
(integer) 3
zrank 找下标
127.0.0.1:6379> zrange zset01 0 -1 withscores
1) "v1"
2) "60"
3) "v2"
4) "70"
5) "v3"
6) "80"
7) "v4"
8) "90"
127.0.0.1:6379> zrank zset01 v4
(integer) 3
zrevrank 逆序获得下标值
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> zrevrank zset01 v4
(integer) 0
zrevrange 逆序遍历
127.0.0.1:6379> zrange zset01 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> zrevrange zset01 0 -1
1) "v4"
2) "v3"
3) "v2"
4) "v1"
zrevrangebyscore
127.0.0.1:6379> zrange zset01 0 -1 withscores
1) "v1"
2) "60"
3) "v2"
4) "70"
5) "v3"
6) "80"
7) "v4"
8) "90"
127.0.0.1:6379> zrevrangebyscore zset01 90 60
1) "v4"
2) "v3"
3) "v2"
4) "v1"
解析配置文件redis.conf
windows 地址 E: edis edis.windows.conf
Units单位
# Redis configuration file example
# Note on units: when memory size is needed, it is possible to specify
# it in the usual form of 1k 5GB 4M and so forth:
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units are case insensitive so 1GB 1Gb 1gB are all the same.
- 配置大小单位,开头定义了一些基本单位,只支持bytes,不支持bit
- 对大小写不敏感
Includes包含
################################## INCLUDES ###################################
# Include one or more other config files here. This is useful if you
# have a standard template that goes to all Redis servers but also need
# to customize a few per-server settings. Include files can include
# other files, so use this wisely.
#
# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
# from admin or Redis Sentinel. Since Redis always uses the last processed
# line as value of a configuration directive, you'd better put includes
# at the beginning of this file to avoid overwriting config change at runtime.
#
# If instead you are interested in using includes to override configuration
# options, it is better to use include as the last line.
#
# include .path olocal.conf
# include c:path oother.conf
可以通过includes包含,redis.conf可以作为总闸,包含其它
General通用
...
redis的持久化
rdb(redis datebase)
是什么?
在指定的时间间隔内将内存中的数据集快照写入磁盘
也就是行话讲的snapshot快照,它恢复时是将快照文件直接读到内存里
aof(append only file)
。。。