数据库学习笔记04- redis

5, Redis 基础

redis -- KV 数据库 -- 内存 -- 单线程+异步i/o (多路io复用)

计算密集型应用:多进程+多进程

IO密集型应用:单线程+异步IO(协程)

2008年 -- redis --》 REmote DIctionary Service

冷数据(不经常使用)/ 热数据(经常使用)

  1. 高速缓存服务(用户经常访问的内容从数据库搬到内存)
  2. 实时排行榜
  3. 投票点赞
  4. 消息队列

redis 命令集: http://redisdoc.com/

安装redis

#1,下载redis到data目录,可以指定版本
wget https://download.redis.io/releases/redis-6.2.7.tar.gz
#2,解压缩redis
tar -xzvf redis-6.2.7.tar.gz
#3,将redis文件移动到local目录
mv redis-6.2.7 /usr/local/redis
#4,安装redis依赖gcc,如果之前已经安装,可省略这一步
yum install gcc -y
#5,编译安装redis,默认安装路径为/usr/local/bin目录
cd /usr/local/redis/
make && make install
#6,启动redis服务器端,推荐后台启动
redis-server ./redis.conf > redis.log &
redis-server --port 6379  --requirepass 1qaz2wsx --appendonly yes
#或者
# 打开redis命令:
service redis start
#启动redis客户端
redis-cli -h hostIP -p port
# 关闭redis命令:
service redis stop
#7,查看redis进程
jobs
[1]+  运行中               redis-server > redis.log &
#8,关闭redis
redis-cli shutdown
[1]+  完成                  redis-server > redis.log

redis基本操作

#进入本机redis
redis-cli
#进入远程redis
redis-cli -h hostname/ip 
#测试连接
127.0.0.1:6379> ping
PONG
#写数据
127.0.0.1:6379> set username forrest 
OK
#读数据
127.0.0.1:6379> get username
"forrest"
#写数据加过期时间
127.0.0.1:6379> set 18911112222 423567 ex 300
OK
127.0.0.1:6379> ttl 18911112222
#退出redis客户端
127.0.0.1:6379> quit
#测试redis性能,自动执行
redis-benchmark
#基本操作命令
[root@node1 redis]# redis-cli
#查看键值
127.0.0.1:6379> keys *
1) "mylist"
2) "username"
3) "key:__rand_int__"
4) "myhash"
5) "counter:__rand_int__"
#查看键的类型
127.0.0.1:6379> type username
string
#选择数据库,默认建16个数据库
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> set k1 v1
OK
#删除数据库中的内容
127.0.0.1:6379[1]> flushdb
OK
#删除所有数据库中的内容
127.0.0.1:6379[1]> flushall
OK
#一次设置多个key value
127.0.0.1:6379[1]> mset username forest password 1qaz2wsx
OK

哈希存储和哈希算法

哈希存储-- 性能非常好的存储方案 --> set

obj --> 哈希函数 --> 哈希码(散列码) --> 对象在内存中存储的位置

文件 --> MD5 / SHA1 / SHA256 --> 哈希码

import hashlib

def cal_hash():
    # md5 / sha1 / sha256
    digester = hashlib.md5()
    with open('requirements.txt','rb') as file_stream:
        # 旧的做法
        # data = file_stream.read(1024)
        # while data:
        #     digester.update(data)
        #     data = file_stream.read(1024)
        #使用迭代器,将文件改造为可迭代对象
        file_iter = iter(lambda: file_stream.read(1024),b'')
        for data in file_iter:
            digester.update(data)
        print(digester.hexdigest())

if __name__ == '__main__':
    cal_hash()
#结果
ce443990290e094adeccfb4f21ee2d43

redis数据类型:hash + list +set + zset

hash表

#哈希表 hset key field value
[root@node1 ~]# redis-cli
#写入键值对
127.0.0.1:6379> hset stu1 id 1001
(integer) 1
#一次写入多个键值对
127.0.0.1:6379> hmset stu1 name yunqianqian gender female birth 1995-01-01 tel 13330116688
OK
#获取键值对
127.0.0.1:6379> hget stu1 id
"1001"
#一次获取所有键值对
127.0.0.1:6379> hvals stu1
1) "1001"
2) "yunqianqian"
3) "female"
4) "1995-01-01"
5) "13330116688"
127.0.0.1:6379> hgetall stu1
 1) "id"
 2) "1001"
 3) "name"
 4) "yunqianqian"
 5) "gender"
 6) "female"
 7) "birth"
 8) "1995-01-01"
 9) "tel"
10) "13330116688"
#删除字段
127.0.0.1:6379> hdel stu1 tel
(integer) 1
#查看类型
127.0.0.1:6379> type stu1
hash

列表list

#列表
#从左往右放数据
127.0.0.1:6379> lpush numbers 10 20 30 40 50
(integer) 5
#展示数据
127.0.0.1:6379> lrange numbers 0 -1
1) "50"
2) "40"
3) "30"
4) "20"
5) "10"
#获取数据 lpop numbers [count]
127.0.0.1:6379> lpop numbers 3
1) "50"
2) "40"
3) "30"
#从右往左放数据
127.0.0.1:6379> rpush numbers 10 20 30 40 50
(integer) 7
127.0.0.1:6379> lrange numbers 0 -1
1) "20"
2) "10"
3) "10"
4) "20"
5) "30"
6) "40"
7) "50"
#每次只取一个元素,取完后最后一个报nil
127.0.0.1:6379> rpop numbers
"50"
127.0.0.1:6379> rpop numbers
"40"
127.0.0.1:6379> rpop numbers
"30"
127.0.0.1:6379> rpop numbers
"20"
127.0.0.1:6379> rpop numbers
"10"
127.0.0.1:6379> rpop numbers
"10"
127.0.0.1:6379> rpop numbers
"20"
127.0.0.1:6379> rpop numbers
(nil)
#取完数据后,类型即为none
127.0.0.1:6379> type numbers
none
127.0.0.1:6379> rpush numbers 10 20 30 40 50
(integer) 5
#重新存放之后,类型为list
127.0.0.1:6379> type numbers
list

集合set

#添加集合set
127.0.0.1:6379> sadd set 10 20 30 10 30 20 50 40 10 20
(integer) 5
#查看集合
127.0.0.1:6379> smembers set
1) "10"
2) "20"
3) "30"
4) "40"
5) "50"
#查看集合个数
127.0.0.1:6379> scard set
(integer) 5
#查看元素是否在集合中,在返回1,不在返回0
127.0.0.1:6379> sismember set 50
(integer) 1
127.0.0.1:6379> sismember set 80
(integer) 0
#添加新集合a b
127.0.0.1:6379> sadd a 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd b 2 4 6 8 9
(integer) 5
#集合a b 求交集
127.0.0.1:6379> sinter a b
1) "2"
2) "4"
#集合a b 求并集
127.0.0.1:6379> sunion a b
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "8"
8) "9"
#集合a b 求差集
127.0.0.1:6379> sdiff a b
1) "1"
2) "3"
3) "5"
#取集合元素
127.0.0.1:6379> spop a
"5"
127.0.0.1:6379> spop a 2
1) "3"
2) "4"
#查看剩余元素
127.0.0.1:6379> smembers a
1) "1"
2) "2"
#查看类型
127.0.0.1:6379> type a
set

有序集合 -- zset

#添加键值对
127.0.0.1:6379> zadd phb 100 chengzi 150 xiaoying 200 forest 380 orange
(integer) 4
#查看,默认升序排列
127.0.0.1:6379> zrange phb 0 -1
1) "chengzi"
2) "xiaoying"
3) "forest"
4) "orange"
#降序查看
127.0.0.1:6379> zrevrange phb 0 -1
1) "orange"
2) "forest"
3) "xiaoying"
4) "chengzi"
#给某个值刷票
127.0.0.1:6379> zincrby phb 1000 xiaoying
"1150"
127.0.0.1:6379> zrevrange phb 0 -1
1) "xiaoying"
2) "orange"
3) "forest"
4) "chengzi"
127.0.0.1:6379> zincrby phb 950 forest
"1150"
127.0.0.1:6379> zrevrange phb 0 -1
1) "xiaoying"
2) "forest"
3) "orange"
4) "chengzi"
127.0.0.1:6379>  

redis地理位置距离计算

#添加地图坐标点,经度 纬度,
127.0.0.1:6379> geoadd map 104.0763 30.6234 libao 104.6072 30.6333 shumagc 104.7172 31.4594 mianyang
(integer) 3
#计算出来的是坐标点之间的直线距离,默认单位为米
127.0.0.1:6379> geodist map libao mianyang
"111249.2758"
127.0.0.1:6379> geodist map libao mianyang km
"111.2493"
#查看某坐标点50km 半径内的点
127.0.0.1:6379> georadius map 104.0 31.0 50 km
1) "libao"
127.0.0.1:6379> georadius map 104.0 31.0 50 km withdist
1) 1) "libao"
   2) "42.5173"
127.0.0.1:6379> georadius map 104.0 31.0 100 km withdist
1) 1) "libao"
   2) "42.5173"
2) 1) "shumagc"
   2) "70.9060"
3) 1) "mianyang"
   2) "85.2276"
127.0.0.1:6379> type map
zset

pycharm 连接redis

python 代码

import redis

def con_redis():
    client = redis.Redis(host= '192.168.1.10',port= 6379, password='1qaz2wsx')
    # client = redis.Redis(host= '192.168.1.10',port= 6379)
    print(client)
    client.set('username','hellokatty',ex=300)
    print(client.ttl('username'))
    print(client.get('username').decode())
    client.set('nickname','forest')
    print(client.get('nickname').decode())
    client.set('Jerry',200)
    client.incr('Jerry')
    print(client.get('Jerry').decode())
    client.incrby('Jerry',180)
    print(client.get('Jerry').decode())
    client.hset('student1','id',1001)
    client.hset('student1','name','莫晓光')
    print(client.hgetall('student1'))
    print(client.hget('student1','name').decode())
    client.rpush('list1',10,20,30,40,50)
    print(client.lrange('list1',0,-1))

if __name__ == '__main__':
    con_redis()

可能会出现报错 远程主机拒绝连接:

redis.exceptions.ConnectionError: Error 10061 connecting to 192.168.1.10:6379. No connection could be made because the target machine actively refused it.

解决办法:注释掉redis配置文件中的绑定本地主机 bind相关的都给注释掉,加上protected-mode no,关闭防火墙,然后重启redis

# Examples:
#
# bind 192.168.1.10               # listens on two specific IPv4 addresses
# bind 127.0.0.1 ::1              # listens on loopback IPv4 and IPv6
# bind * -::*                     # like the default, all available interfaces
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only on the
# IPv4 and IPv6 (if available) loopback interface addresses (this means Redis
# will only be able to accept client connections from the same host that it is
# running on).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT OUT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# bind 127.0.0.1 -::1
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
#protected-mode yes
posted @ 2022-10-16 21:52  逆流的鱼2016  阅读(51)  评论(0编辑  收藏  举报