码迷,mamicode.com
首页 > 数据库 > 详细

Paramiko和MySQL相关-day10

时间:2018-04-01 00:03:56      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:count   com   ==   提交   bsp   集合   常用   param   test   

本章内容

  1. paramiko基本使用
  2. MySQL基础语法
  3. pymysql模块使用
  4. Python操作memcached
  5. Python操作redis

 

一、paramiko模块基本使用

 paramiko是Python的一个模块,如果电脑没有装这个模块的话需要使用pip3 install paramiko。paramiko模块的主要功能是连接服务器并在远端服务器执行命令并把结果返回到本地。目前很多自动化工具也用的是该模块,比如ansible。

 

  - 基于SSH密码登陆

import paramiko

#创建一个ssh socket对象
ssh_client = paramiko.SSHClient()
#允许连接不在know_hosts文件中的主机
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接到ssh服务器
ssh_client.connect(hostname=95.163.199.239,port=端口,username=root,password=passwd,timeout=56)
#执行命令,
stdin,stdout,stderr = ssh_client.exec_command(df)
#获取结果,结果是bytes类型
result = stdout.read()
result_str = result.decode(utf-8)
print(result_str)
#关闭连接
ssh_client.close()

 

技术分享图片
transport = paramiko.Transport((95.163.199.239,端口))
transport.connect(username=用户,password=密码)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin,stdout,stderr = ssh.exec_command(df)
print(stdout.read().decode(utf-8))
transport.close()
transport方式

 

 

  - 基于RSA秘钥登陆

#创建秘钥的文件对象
key_file = open(rE:\filename\filename\id_rsa_2048)
#服务器的秘钥
rsa_key = paramiko.RSAKey.from_private_key(key_file,rsa_password)
#连接ssh服务器
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#登陆服务器携带秘钥
ssh.connect(hostname=95.163.199.239,port=端口,username=root,pkey=rsa_key)
stdin,stdout,stderr = ssh.exec_command(df)
print(stdout.read().decode(utf-8))
ssh.close()

 

技术分享图片
key_file = open(rE:\filename\filename\id_rsa_2048)
rsa_key = paramiko.RSAKey.from_private_key(key_file,rsa_password)
transport = paramiko.Transport((95.163.199.239,port))
transport.connect(username=root,pkey=rsa_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin,stdout,stderr = ssh.exec_command(df)
print(stdout.read().decode(utf-8))
transport.close()
transport方式

  

  - 使用paramiko对文件进行上传和下载

  

import paramiko

transport = paramiko.Transport((hostname,22))
transport.connect(username=leon,password=123)
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(/tmp/location.py, /tmp/test.py)
# 将remove_path 下载到本地 local_path
sftp.get(remove_path, local_path)

  - 基于秘钥的上传下载

import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file(/home/auto/.ssh/id_rsa)
 
transport = paramiko.Transport((hostname, 22))
transport.connect(username=leon, pkey=private_key )
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(/tmp/location.py, /tmp/test.py)
# 将remove_path 下载到本地 local_path
sftp.get(remove_path, local_path)
技术分享图片
class SSH_Client(object):
    def __init__(self,host=None,port=None,username=None,password=None):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self._transport = None

    def run(self):
        self.conn()

    def conn(self):
        transport = paramiko.Transport((self.host,self.port))
        transport.connect(username=self.username,password=self.password)
        self._transport = transport
    def close(self):
        self._transport.close()

    def command(self):
        ssh = paramiko.SSHClient()
        ssh._transport = self._transport
        while True:
            command = input([localhost~]#:).strip()
            if command:
                if command == "exit":
                    self.close()
                    exit()
                else:
                    stdin,stdout,stderr = ssh.exec_command(command)
                    print(stdout.read().decode(utf-8))
            else:
                continue


ssh = SSH_Client()
ssh.run()
练习

 

二、MySQL的基本语法

  

  -用户管理

      创建用户-  create user ‘username‘@‘ipaddr‘ identified by ‘password‘;
    - 删除用户 drop user ‘username‘@‘ipaddr‘;
    - 修改用户 rename user ‘username‘@‘ipaddr‘ to ‘new_username‘@‘ipaddr‘;
    - 修改密码 set password for ‘username‘@‘ipaddr‘ = Password(‘new_password‘);

    - 查看目前所有用户 select host,user from mysql.user;


  授权管理:

    show grants for ‘username‘@‘ipaddr‘; - 查看权限
    grant 权限 on 数据库.表 to ‘用户名‘@‘密码‘ 授权管理:
    revoke 权限 on 数据库.表 from ‘用户名‘@‘密码‘ 移除权限

            all privileges  除grant外的所有权限
            select          仅查权限
            select,insert   查和插入权限
            ...
            usage                   无访问权限
            alter                   使用alter table
            alter routine           使用alter procedure和drop procedure
            create                  使用create table
            create routine          使用create procedure
            create temporary tables 使用create temporary tables
            create user             使用create user、drop user、rename user和revoke  all privileges
            create view             使用create view
            delete                  使用delete
            drop                    使用drop table
            execute                 使用call和存储过程
            file                    使用select into outfile 和 load data infile
            grant option            使用grant 和 revoke
            index                   使用index
            insert                  使用insert
            lock tables             使用lock table
            process                 使用show full processlist
            select                  使用select
            show databases          使用show databases
            show view               使用show view
            update                  使用update
            reload                  使用flush
            shutdown                使用mysqladmin shutdown(关闭MySQL)
            super                   ????使用change master、kill、logs、purge、master和set global。还允许mysqladmin????????调试登陆
            replication client      服务器位置的访问
            replication slave       由复制从属使用
技术分享图片
用户名@IP地址         用户只能在改IP下才能访问
 用户名@192.168.1.%   用户只能在改IP段下才能访问(通配符%表示任意)
用户名@%   用户可以再任意IP下访问(默认IP地址为%)
可用的ip格式
技术分享图片
grant all privileges on db1.tb1 TO 用户名@IP

            grant select on db1.* TO 用户名@IP

            grant select,insert on *.* TO 用户名@IP

            revoke select on db1.tb1 from 用户名@IP

示例
示例

 

  PS:在每句MySQL语句后面都会有一个;(分号)

 

  基本操作

create database db1; - 创建一个数据库
drop database db1: - 删除一个数据库
show databases - 查看所有库
use db1; - 进入数据库
create table tb1(id int not null auto_increment primary key,name char(20) null,age int not null)engine=innodb; -创建一个表,engine=innodb支持事务性操作
insert into tb1(name,age) values (leon,20); -插入输入
select * from db1.tb1; -查询特定表的数据
select name from db1.tb1 ; -查询特定表的数据
update tb1 set age=68; - 所有表中的age列都是68
update tb1 set age=68 where id=2;- 更新指定数据
delete from tb1; - 删除表里面的所有数据
delete from tb1 where id >1; -删除特定数据
alter table 表名 add 列明 类型: -添加列
alter table 表名 drop column 列名; -删除列
alter table 表名 modify column 列名 类型; --修改列
alter table 表名 change 源列名 新列名 类型 -修改列
        foreign key 一对多
        create table deparment(id int not null,title char(32) null,);
        create table tb1(id int not null primary key,username char(32) null,deparment_id int not null,constraint fk_cc foreign key (deparment_id) references deparment(id));
        - constraint:约束
        - fk_cc:外键的名字可以任意
        - (deparment_id)需要外键的列
        - references deparment(id):外键到department表的ID列
技术分享图片
多对多
        create table deparment(id int not null auto_increment primary key,title char(32) null,)
        
        create table host(id int not null auto_increment primary key,ip char(32) null,port int null,)
        
        create table deparment_to_host(id int not null auto_increment primary key,did int not null,hid int not null,constraint fk_did_deparment foreign key (did) references deparment(id),constraint fk_hid_host foreign key (hid) references host(id))
多对多关系

技术分享图片

技术分享图片
bit[(M)]
            二进制位(101001),m表示二进制位的长度(1-64),默认m=1

        tinyint[(m)] [unsigned] [zerofill]

            小整数,数据类型用于保存一些范围的整数数值范围:
            有符号:
                -128127.
            无符号:
~ 255

            特别的: MySQL中无布尔值,使用tinyint(1)构造。

        int[(m)][unsigned][zerofill]

            整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                    -21474836482147483647
                无符号:
~ 4294967295

            特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为: 00002

        bigint[(m)][unsigned][zerofill]
            大整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                    -92233720368547758089223372036854775807
                无符号:
 ~  18446744073709551615

        decimal[(m[,d])] [unsigned] [zerofill]
            准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。

            特别的:对于精确数值计算时需要用此类型
                   decaimal能够存储精确值的原因在于其内部按照字符串存储。

        FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
            单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
                无符号:
                    -3.402823466E+38 to -1.175494351E-38,
                    1.175494351E-38 to 3.402823466E+38
                有符号:
                    1.175494351E-38 to 3.402823466E+38

            **** 数值越大,越不准确 ****

        DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
            双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。

                无符号:
                    -1.7976931348623157E+308 to -2.2250738585072014E-308
                    2.2250738585072014E-308 to 1.7976931348623157E+308
                有符号:
                    2.2250738585072014E-308 to 1.7976931348623157E+308
            **** 数值越大,越不准确 ****


        char (m)
            char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。
            PS: 即使数据小于m长度,也会占用m长度
        varchar(m)
            varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。

            注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡

        text
            text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 ? 1)个字符。

        mediumtext
            A TEXT column with a maximum length of 16,777,215 (2**24 ? 1) characters.

        longtext
            A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 ? 1) characters.


        enum
            枚举类型,
            An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
            示例:
                CREATE TABLE shirts (
                    name VARCHAR(40),
                    size ENUM(x-small, small, medium, large, x-large)
                );
                INSERT INTO shirts (name, size) VALUES (dress shirt,large), (t-shirt,medium),(polo shirt,small);

        set
            集合类型
            A SET column can have a maximum of 64 distinct members.
            示例:
                CREATE TABLE myset (col SET(a, b, c, d));
                INSERT INTO myset (col) VALUES (a,d), (d,a), (a,d,a), (a,d,d), (d,a,d);

        DATE
            YYYY-MM-DD(1000-01-01/9999-12-31)

        TIME
            HH:MM:SS(-838:59:59/838:59:59)

        YEAR
            YYYY(1901/2155)

        DATETIME

            YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59    Y)

        TIMESTAMP

            YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
MySQL可用的数据类型
技术分享图片
a、条件
    select * fromwhere id > 1 and name != alex and num = 12;
 
    select * fromwhere id between 5 and 16;
 
    select * fromwhere id in (11,22,33)
    select * fromwhere id not in (11,22,33)
    select * fromwhere id in (select nid from 表)
 
b、通配符
    select * fromwhere name like ale%  - ale开头的所有(多个字符串)
    select * fromwhere name like ale_  - ale开头的所有(一个字符)
 
c、限制
    select * from 表 limit 5;            - 前5行
    select * from 表 limit 4,5;          - 从第4行开始的5行
    select * from 表 limit 5 offset 4    - 从第4行开始的5行
 
d、排序
    select * from 表 order by 列 asc              - 根据 “列” 从小到大排列
    select * from 表 order by 列 desc             - 根据 “列” 从大到小排列
    select * from 表 order by 列1 desc,列2 asc    - 根据 “列1” 从大到小排列,如果相同则按列2从小到大排序
 
e、分组
    select num from 表 group by num
    select num,nid from 表 group by num,nid
    select num,nid fromwhere nid > 10 group by num,nid order nid desc
    select num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nid
 
    select num from 表 group by num having max(id) > 10
 
    特别的:group by 必须在where之后,order by之前
 
f、连表
    无对应关系则不显示
    select A.num, A.name, B.name
    from A,B
    Where A.nid = B.nid
 
    无对应关系则不显示
    select A.num, A.name, B.name
    from A inner join B
    on A.nid = B.nid
 
    A表所有显示,如果B中无对应关系,则值为null
    select A.num, A.name, B.name
    from A left join B
    on A.nid = B.nid
 
    B表所有显示,如果B中无对应关系,则值为null
    select A.num, A.name, B.name
    from A right join B
    on A.nid = B.nid
 
g、组合
    组合,自动处理重合
    select nickname
    from A
    union
    select name
    from B
 
    组合,不处理重合
    select nickname
    from A
    union all
    select name
    from B
MySQL的其他操作

   关于分组和连表操作的说明

技术分享图片
-- show tables;
-- create TABLE nothing(id int not NULL auto_increment PRIMARY KEY,name CHAR(20) null);
-- show tables;
-- create student(sid INT not null auto_increment PRIMARY key,name char(20) not null,
-- student_cid)
-- create table tearcher(tid int not NULL auto_increment PRIMARY KEY,tearcher_name char(20) null)
-- create table class(cid int not null auto_increment PRIMARY key,
-- class_name char(20),
-- class_tid int not null,
-- CONSTRAINT fk_class_tid_to_tearcher FOREIGN KEY (class_tid) REFERENCES tearcher(tid));

-- CREATE TABLE student(
-- id int not null auto_increment PRIMARY KEY,
-- student_name CHAR(20),
-- student_cid int not NULL,
-- CONSTRAINT student_cid_to_class FOREIGN KEY (student_cid) REFERENCES class(cid)
-- );

-- create table course(
-- cid int not null auto_increment PRIMARY key,
-- course_name char(20),
-- course_tid INT not NULL,
-- CONSTRAINT student_cid_to_tearcher FOREIGN KEY (course_tid) REFERENCES tearcher(tid)
-- );

-- create table score(sid int not null auto_increment PRIMARY KEY,
-- number int,
-- score_sid int not NULL,
-- score_cid int not NULL,
-- CONSTRAINT score_sid_to_student FOREIGN KEY (score_sid) REFERENCES student(id),
-- CONSTRAINT score_cid_to_course FOREIGN KEY (score_cid) REFERENCES course(cid)
-- );

-- INSERT INTO tearcher(tearcher_name) VALUES("张三");
-- INSERT INTO tearcher(tearcher_name) VALUES("李四");
-- INSERT INTO tearcher(tearcher_name) VALUES("王二");
-- INSERT INTO tearcher(tearcher_name) VALUES("天道");

-- INSERT INTO class(class_name,class_tid)  VALUES (‘四年三班‘,‘1‘);
-- INSERT INTO class(class_name,class_tid)  VALUES (‘四年四班‘,‘2‘);
-- INSERT INTO class(class_name,class_tid)  VALUES (‘四年五班‘,‘3‘);
-- INSERT INTO class(class_name,class_tid)  VALUES (‘四年六班‘,‘4‘);
-- INSERT INTO class(class_name,class_tid)  VALUES (‘五年一班‘,‘1‘);

-- INSERT INTO student(student_name,student_cid) VALUES (‘Leon‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘麻子‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘胡志虎‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘乔jj‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘老毛‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘张累‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘张耀‘,‘1‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘瑶瑶‘,‘2‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘小明‘,‘2‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘小王‘,‘2‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘小花‘,‘2‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘陈丹丹‘,‘3‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘老魏‘,‘3‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘天机‘,‘3‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘大师‘,‘4‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘若尘‘,‘4‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘明镜‘,‘4‘);
-- INSERT INTO student(student_name,student_cid) VALUES (‘明堂‘,‘4‘);


-- INSERT INTO course(course_name,course_tid) VALUES (‘生物‘,‘1‘);
-- INSERT INTO course(course_name,course_tid) VALUES (‘语文‘,‘2‘);
-- INSERT INTO course(course_name,course_tid) VALUES (‘数学‘,‘3‘);
-- INSERT INTO course(course_name,course_tid) VALUES (‘英文‘,‘4‘);

-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘20‘,‘1‘,‘1‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘30‘,‘1‘,‘2‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘40‘,‘1‘,‘3‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘50‘,‘1‘,‘4‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘50‘,‘2‘,‘1‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘40‘,‘2‘,‘2‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘30‘,‘2‘,‘3‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘20‘,‘2‘,‘4‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘25‘,‘3‘,‘1‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘15‘,‘3‘,‘2‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘35‘,‘3‘,‘3‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘45‘,‘3‘,‘4‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘45‘,‘4‘,‘1‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘35‘,‘4‘,‘2‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘25‘,‘4‘,‘3‘);
-- INSERT INTO score(number,score_sid,score_cid) VALUES (‘15‘,‘4‘,‘4‘);
建表操作

  - 各表之间的关系(PRIMARY KEY)

技术分享图片

 

  - 查看每个班级有哪些学生

   所涉及到连表查询,(left join、right join,inter join)首先前面两者没有什么区别,而后面的inter join在连表的时候会把列中有null的字眼的那一行给去掉

select * from class LEFT JOIN student on class.class_tid = student.student_cid; --普通连表查询
SELECT cid,class_name,student_name from class LEFT JOIN student  on class.class_tid = student.student_cid; --过滤指定列连表
SELECT CS.cid,CS.class_name,ST.student_name from class as CS
 LEFT JOIN student as ST  on CS.class_tid = ST.student_cid; -- 给表起一个别名
SELECT CS.cid as 班级id,CS.class_name as 班级名称,ST.student_name as 学生名称 from class as CS
 LEFT JOIN student as ST  on CS.class_tid = ST.student_cid; -- 给列起一个别名

 

   - 查看每个班级里面有多少学生

  这面会用到group by 也就是分组的操作。而在分组的时候加条件语句的时候就不是where而是having

SELECT count(CS.cid) as 班级人数,CS.class_name as 班级名称 from class as CS 
LEFT JOIN student as ST  on CS.class_tid = ST.student_cid GROUP BY CS.cid; --分组实际上也就是去重,在这里cid的不同代表着一个班级的不同,二count是一个函数,像这样的函数还有max,min,sum等
SELECT count(CS.cid) as 班级人数,CS.class_name as 班级名称 from class as CS 
LEFT JOIN student as ST  on CS.class_tid = ST.student_cid GROUP BY CS.cid HAVING count(CS.cid) > 4;--查询班级人数大于4的班级

 

  - python 操作mysql的模块pymysql

  pymysql是Python3用来操作MySQL的模块,使用该模块的时候也需要相对的sql功底。基本原理也是创建一个socket连接对端的mysql服务器上面,通过自己写的sql语言在远端执行。

import pymysql
#创建一个连接到mysql上面
conn = pymysql.connect(host=95.163.199.239,port=3306,user=leon,passwd=abc123,db=test)
#创建一个游标,来操作sql语句
cursor = conn.cursor()
#执行SQL语句,并返回受到影响的行数
effect_row = cursor.execute(show tables)
#res是返回结果,数据类型是元组,
#PS fetchall()是返回所有的结果,fetchmant(3)是返回三个结果,fetchone()是返回第一个结果
res = cursor.fetchall()
print(res)
#提交刚刚执行的SQL语句,如果不执行,刚刚执行的不生效
conn.commit()
#关闭游标
cursor.close()
#关闭结果
conn.close()

 

  有时候返回的数据类型是元组并不是我们想要的,通过在游标出添加一下东西我们可以是返回的数据类型为字典

import pymysql
#创建一个连接到mysql上面
conn = pymysql.connect(host=95.163.199.239,port=3306,user=leon,passwd=abc123,db=test)
#创建一个游标,来操作sql语句,返回的数据类型是字典类型
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#执行SQL语句,并返回受到影响的行数
effect_row = cursor.execute(show tables)
#res是返回结果,数据类型是元组,
#PS fetchall()是返回所有的结果,fetchmant(3)是返回三个结果,fetchone()是返回第一个结果
res = cursor.fetchall()
print(res)
#提交刚刚执行的SQL语句,如果不执行,刚刚执行的不生效
conn.commit()
#关闭游标
cursor.close()
#关闭结果
conn.close()

 

4.Python操作memcached

 - memcached基础:

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

memcached安装、启动

wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install
 
PS:依赖libevent
       yum install libevent-devel
       apt-get install libevent-dev

启动memcached

memcached -d -m 10    -u root -l 192.168.1.5 -p 12000 -c 256 -P /tmp/memcached.pid
 
参数说明:
    -d 是启动一个守护进程
    -m 是分配给Memcache使用的内存数量,单位是MB
    -u 是运行Memcache的用户
    -l 是监听的服务器IP地址
    -p 是设置Memcache监听的端口,最好是1024以上的端口
    -c 选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
   -P 是设置保存Memcache的pid文件

Python操作memcached的模块需要在网上下载

下载地址是:https://pypi.python.org/pypi/python-memcached

安装:进入到下载完成的目录,并在此目录下面打开命令行窗口:使用python setup.py install 进行安装

 

基本操作: #更加详细的版本

import memcache

conn = memcache.Client([192.168.1.8:12000],debug=True)
conn.set(k1,v1)
print(conn.get(k1))
#conn = .....创建了一个socket连接到memcached服务器
#conn.set 是往memcached中插入一条数据,在memcached中值支持一种数据类型——字典
#conn.get是获取键为**的值
#debug=True:是否在服务器上显示错误消息,当无法联系。--->这个是源码中注释的时候解释

memcached支持集群

python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比。

  • 根据算法将 k1 转换成一个数字
  • 这个主机的权重是多少就会在这个列表中出现多少次
  • 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
  • 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
  • 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中
  • 源码中截图
  • 技术分享图片

     

技术分享图片
conn= memcache.Client([(1.1.1.1:12000, 1), (1.1.1.2:12000, 2), (1.1.1.3:12000, 1)], debug=True)

conn.set(k1,v1)
分布式

 

python-memcached的一大堆操作:

 

add

 添加一条键值对,如果已经存在的 key,重复执行add操作异常

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
mc.add(k1, v1)
# mc.add(‘k1‘, ‘v2‘) # 报错,对已经存在的key重复添加,失败!!!

replace

replace 修改某个key的值,如果key不存在,则异常

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
# 如果memcache中存在kkkk,则替换成功,否则一场
mc.replace(kkkk,999)

set 和 set_multi

set            设置一个键值对,如果key不存在,则创建,如果key存在,则修改
set_multi   设置多个键值对,如果key不存在,则创建,如果key存在,则修改

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
 
mc.set(key0, ‘value0)
 
mc.set_multi({key1: val1, key2: val2})

delete 和 delete_multi

delete             在Memcached中删除指定的一个键值对
delete_multi    在Memcached中删除指定的多个键值对

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
 
mc.delete(key0)
mc.delete_multi([key1, key2])

get 和 get_multi

get            获取一个键值对
get_multi   获取多一个键值对

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
 
val = mc.get(key0)
item_dict = mc.get_multi(["key1", "key2", "key3"])

append 和 prepend

append    修改指定key的值,在该值 后面 追加内容
prepend   修改指定key的值,在该值 前面 插入内容

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
# k1 = "v1"
 
mc.append(k1, after)
# k1 = "v1after"
 
mc.prepend(k1, before)
# k1 = "beforev1after"

decr 和 incr  

incr  自增,将Memcached中的某一个值增加 N ( N默认为1 )
decr 自减,将Memcached中的某一个值减少 N ( N默认为1 )

import memcache
 
mc = memcache.Client([10.211.55.4:12000], debug=True)
mc.set(k1, 777)
 
mc.incr(k1)
# k1 = 778
 
mc.incr(k1, 10)
# k1 = 788
 
mc.decr(k1)
# k1 = 787
 
mc.decr(k1, 10)
# k1 = 777

gets 和 cas

如商城商品剩余个数,假设改值保存在memcache中,product_count = 900
A用户刷新页面从memcache中读取到product_count = 900
B用户刷新页面从memcache中读取到product_count = 900

如果A、B用户均购买商品

A用户修改商品剩余个数 product_count=899
B用户修改商品剩余个数 product_count=899

如此一来缓存内的数据便不在正确,两个用户购买商品后,商品剩余还是 899
如果使用python的set和get来操作以上过程,那么程序就会如上述所示情况!

如果想要避免此情况的发生,只要使用 gets 和 cas 即可,如:

import memcache
mc = memcache.Client([10.211.55.4:12000], debug=True, cache_cas=True)
 
v = mc.gets(product_count)
# ...
# 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生
mc.cas(product_count, "899")

Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。

 

 

Redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

1. 使用Redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2) 支持丰富数据类型,支持string,list,set,sorted set,hash

(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除


2. redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据


3. redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。



 

4. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

 相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

 

5. Memcache与Redis的区别都有哪些?

1)、存储方式

Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型

Memcache对数据类型支持相对简单。

Redis有复杂的数据类型。


3),value大小

redis最大可以达到1GB,而memcache只有1MB



6. Redis 常见的性能问题都有哪些?如何解决?

 

1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。


2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

 
3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内




7, redis 最适合的场景


Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?

       如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
、Redis支持数据的备份,即master-slave模式的数据备份。
、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

(1)、会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

(2)、全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件  wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

(3)、队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

(4),排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

(5)、发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。

 

redis的下载和安装

wget http://download.redis.io/releases/redis-3.0.6.tar.gz

tar xzf redis-3.0.6.tar.gz
cd redis-3.0.6
make
src/redis-server -->启动
#启动客户端
src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
 
Python操作redis模块
pip3 install redis 
 
 

API使用

redis-py 的API的使用可以分类为:

  • 连接方式
  • 连接池
  • 操作
    • String 操作
    • Hash 操作
    • List 操作
    • Set 操作
    • Sort Set 操作
  • 管道
  • 发布订阅

 

基本连接

redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。

import redis

#连接redis 服务器
conn = redis.Redis(host=192.168.1.8,port=6379)
#插入一个值
conn.set(k1,v1)
#获取这个值
print(conn.get(k1))

连接池

redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。

import redis
pool = redis.ConnectionPool(host=192.168.1.8,port=6379,max_connections=10)
conn = redis.Redis(connection_pool=pool)

conn.set(k1,CHEN)
print(conn.get(k1))

 

 

Paramiko和MySQL相关-day10

标签:count   com   ==   提交   bsp   集合   常用   param   test   

原文地址:https://www.cnblogs.com/yanlinux/p/8625423.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!