存档

‘数据库’ 分类的存档

如何将redis一个list中的数据全部移动到另一个list

2018年7月21日 没有评论

有时候我们需要将一个list中的数据全部移动到另一个list中,而Redis目前没有直接提供这样的命令。

怎么办?

很简单,逐一pop出list a中的数据,再push到list b中。当然pop+push可以通过rpoplpush来实现。所以对源list做个遍历就行了。

#!/bin/sh

host=”127.0.0.1″
port=”6379″
passwd=”foobar”
srcList=”listSrc”
dstList=”listDest”

while[ 1 == 1 ];do
ret=$(redis-cli -h $host -p $port -a $passwd rpoplpush $srcList $dstList)
[ -z $ret ] && return
done

分类: Redis 标签:

非root用户启动和运行redis

2018年5月30日 没有评论

    redis之前爆出过一个漏洞,攻击者可藉此漏洞获取系统root权限。在之前的文章里,我们了解了如何增强redis的安全性。我们还可以使用非root用户来运行redis,进而进一步提升系统安全性。

  1. 以root身份正常安装redis
  2. 切换非root用户登入系统,比如test
  3. 拷贝redis默认配置文件到test的根目录(或其他test有访问权限的目录):

    sudo copy /etc/redis/6379.conf /home/test/

  4. 修改test下配置文件的属主:

    sudo chown test.test /home/test/6379.conf

  5. 修改配置文件中redis运行使用到的相关文件和目录的路径,可通过grep 6379 /home/test/6379.conf查找这些文件和目录,将这些路径修改到test用户根目录下

    pidfile /home/test/run/redis_6379.pid
    logfile /home/test/log/redis_6379.log
    dir /home/test/lib/redis/6379

  6. 创建这些文件和目录

    mkdir -p /home/test/run/ /home/test/log  /home/test/lib/redis/6379

  7. 启动redis

    /usr/local/bin/redis-server /home/test/6379.conf

分类: Redis, 安全, 开发 标签:

python3 PyMySQL模块的安装和使用

2017年10月24日 没有评论

我们知道Python3和Python2是不兼容的,版本由2升级到3之后对MySQL数据库的访问也需要使用新的模块。此前的文章中已介绍过MySQLdb在Python2中的用法,今天介绍PyMySQL在Python3中的用法。

  1. 安装
    • 直接通过pip安装:
      pip install PyMySQL
  2. 示例
    • 连接数据库
    import pymysql
    try:
        conn = pymysql.connect(ip, 3306, user, password, db, charset='utf8', cursorclass=pymysql.cursors.DictCursor)
    except Exception as e:
        print("Exception throwed when connect to db: " + str(e))
    • 插入数据
      try:
          with conn.cursor() as cursor:
              sql = "insert into t_student(id, name) values (%d, %s)"
              rows=cursor.execute(sql, (s.id, s.name))
              conn.commit()
      
              if rows == 1:
                  print("Inserted.")
              else:
                  print("Failed")
      except Exception as e:
          print("Exception throwed when insert data: " + str(e))
分类: mysql, Python, 开发 标签: , ,

一个从MongoDB中导出给定日期范围内数据的shell脚本

2017年6月29日 没有评论

前几天介绍了使用mongoexport的使用方法,结合date命令的使用,这里给出一个完整的脚本,用来从MongoDB中导出某个日期范围内的数据,数据导出后从MongoDB中进行删除

#!/bin/sh
#d1, the beginning date, eg:2017-06-28
d1=$1 
d1=`date -d $d1 +%F`
 
#transfer d1 to seconds
d2=`date -d $d1 +%s`
#increase d1 by one day
d2=`expr $d2 + 86400`
#transfer d2 from seconds to day
d2=`date -d @$d2 +%F`

#build query json
qj='{"time":{$gte:ISODate("'"$d1"'T00:00:00Z")}, "time":{$lt:ISODate("'"$d2"'T00:00:00Z")}}'
#export
./mongoexport --db testDB --collection testColl --query="$qj" --fields="userId,userName" --type="csv" --out results"-$d1" --noHeaderLine

#generate js for delete
echo 'var db = connect("testDB");' > delete.js
echo 'db.testColl.remove({"time":{$gte:ISODate("'"$d1"'T00:00:00Z")}, "time":{$lt:ISODate("'"$d2"'T00:00:00Z")}})' >> delete.js
#delete 
./mongo delete.js

备注:如果MongoDB使用的不是默认端口27017,上面的脚本里mongoexport和mongo都需要增加–port参数,并且delete.js中的connect方法也需要指定端口,指定方式为:

var db = connect("127.0.0.1:port/testDB");
分类: MongoDB, Shell 标签: ,

使用mongoexport导出某个时间段内的数据

2017年6月24日 没有评论

mongoexport是MongoDB自带一个数据导出工具,可以方便的导出查询结果。现通过一条命令来演示使用方法,特别是如何查询某个时间段内的数据。

数据库名称:testDB

集合名称:testColl

查询条件:2017-06-12当天的所有记录

导出列:userId, userName

导出文件类型:csv,不含“表头”

./mongoexport –db testDB –collection testColl –query='{“time”:{$gte:ISODate(“2017-06-12T00:00:00Z”)}, “time”:{$lt:ISODate(“2017-06-13T00:00:00Z”)}}’ –fields=”userId,userName” –type=”csv” –noHeaderLine –out results

请注意加粗参数的用法。

–query:指定查询条件,多个条件可以进行and或or的逻辑组合。此处组合了起止时间。

–fields:指定输出字段,默认输出全部字段

–noHeaderLine:不输出字段名称

官方文档指出:export不适于用作生产环境的全库数据备份,请使用mongodump进行全库备份。

分类: MongoDB 标签:

使用openresty+redis轻松实现网站访问统计

2017年2月16日 没有评论

网站的受访统计是网站运营和优化的一个重要参考数据,对于并发量较大的网站,我们可以通过nginx+redis的架构来简单实现页面受访统计。这主要得益于nginx的高并发性能和redis快速存取内存数据。实际应用中,我们可以使用openresty来快速搭建统计系统。

openresty集合了lua和lua-redis访问库,可以通过编写nginx.conf配置文件实现对redis数据库的存取。简单且高效。

  1. 安装和配置openresty及redis
  2. 修改nginx.conf,示例:

    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    server {
    listen 8088;
    server_name www.test.com;

    location /get_pv {
    set $id_param $args;
    content_by_lua ‘
    local redis_mod = require “resty.redis”
    local redis_db= redis_mod:new()
    redis_db:set_timeout(1000) — 1 second

    local ok, err = redis_db:connect(“127.0.0.1″, 6379)
    if not ok then
    ngx.log(ngx.ERR, “failed to connect to redis: “, err)
    return ngx.exit(500)
    end

    local id = string.sub(ngx.var.id_param, 4)
    local pv, err = redis_db:get(id)
    if not pv then
    redis_db:close()
    ngx.log(ngx.ERR, “failed to get redis key: “, id, err)
    return ngx.exit(500)
    end

    if pv == ngx.null then
    redis_db:close()
    ngx.log(ngx.ERR, “no pv found for “, id)
    return ngx.exit(400)
    end

    redis_db:close()

    ngx.header.content_type = “text/plain”;
    ngx.say(pv)
    ‘;
    }
    }

    server {
    listen 9099;
    server_name www.test.com;

    location /set_pv {
    set $id_param $args;
    content_by_lua ‘
    local redis_mod = require “resty.redis”
    local redis_db= redis_mod:new()
    redis_db:set_timeout(1000) — 1 second

    local ok, err = redis_db:connect(“127.0.0.1″, 6379)
    if not ok then
    ngx.log(ngx.ERR, “failed to connect to redis: “, err)
    return ngx.exit(500)
    end

    local id = string.sub(ngx.var.id_param, 4)
    local pv = redis_db:incr(id)
    if not pv then
    redis_db:close()
    ngx.log(ngx.ERR, “failed to incr redis key: “, id, err)
    return ngx.exit(500)
    end

    redis_db:close()

    ngx.header.content_type = “text/plain”;
    ngx.say(pv)
    ‘;
    }
    }
    }

  3. 在网站页面中部署统计代码

<iframe frameborder=”0″ scrolling=”no” width=”0″  height=”0″ style=”display:none;” src=”http://www.test.com:9099/set_pv?id=page_411“></iframe>

分类: Lua, Redis, 开发 标签: , , ,