删除gemfire缓存中的查询?

时间:2016-05-23 13:50:58

标签: gemfire

当我在gfsh控制台中运行SELECT查询时,它按预期工作:

query --query="SELECT * FROM /channelProfiles_composite_asrd WHERE profile.channelCode='JJ'"

但类似的DELETE查询失败:

query --query="DELETE * FROM /channelProfiles_composite_asrd WHERE profile.channelCode='JJ'"
Result     : false
startCount : 0
endCount   : 20
Message    : Query is invalid due for error : <Syntax error in query:  unexpected token: FROM>

NEXT_STEP_NAME : END

gemfire是否支持DELETE?

5 个答案:

答案 0 :(得分:3)

Geode / GemFire OQL遗憾的是不支持DELETE。您必须迭代结果集并删除“手动”。

答案 1 :(得分:1)

在gfsh提示符下,您可以使用以下删除命令

removing specific keys
data with String keys
remove --region=RegionName --key=abc

使用其他对象键的数据必须使用key-class以及

remove --region=RegionName --key-class=java.lang.Integer --key=1

对于要删除的大量记录,我要做的是使用Select query搜索要删除的键列表。然后构建上述删除命令的脚本并一起运行它们。

删除所有区域数据

remove --region=RegionName --all

否则,您需要使用Gemfire API

删除区域数据的Java程序

答案 2 :(得分:1)

这是我写的一个GemFire函数,它将清除一个区域。如果你抛弃了我们从未最终使用的绒毛和额外功能,这段代码可能会短得多。事后看来,我并不需要同步&#34;被清除的区域列表,因为两个人在同一微秒内调用该函数的几率几乎为零。

我们在GemFire 7和GemFire 8集群中都使用它。将它放入jar并安装后,可以从gfsh调用此函数来清除区域。

import java.util.ArrayList;   
import java.util.Iterator;
import java.util.List;  
import java.util.Properties;    
import java.util.Set;
import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.Declarable;
import com.gemstone.gemfire.cache.EntryNotFoundException;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.execute.Function;
import com.gemstone.gemfire.cache.execute.FunctionContext;
import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
import com.gemstone.gemfire.distributed.DistributedSystem;

public class ClearRegionFunction implements Function, Declarable {
    private static final long serialVersionUID = 1L;
    private static LogWriter log;
    private static List<String> clearingRegionList = new ArrayList<String>();

    static {    
        DistributedSystem ds = CacheFactory.getAnyInstance().getDistributedSystem();
        log = ds.getLogWriter();   
    }

    @Override   
    public void execute(FunctionContext fc) {   
        RegionFunctionContext rfc = (RegionFunctionContext) fc;  
        Region region = rfc.getDataSet();    
        String regionName = region.getName();           

        //If passed a flag of "true", that says to simulate the clear, but don't actually clear.
        //This is used to test if a clear is already in progress, in which case we'd return false.

        Boolean simulate = (Boolean)rfc.getArguments();    
        log.fine("Argument passed = " + simulate);  
        if (simulate == null) simulate = false;       

        if (simulate) {    
            rfc.getResultSender().lastResult( ! clearingRegionList.contains(regionName));    
            return;   
        }

        log.warning("Clearing region: " + regionName); // Used "warning" because clearing a region is serious.   
        try {          
            // Protect against the same region being cleared twice at the same time.     
            synchronized (clearingRegionList) {   
                if (clearingRegionList.contains(regionName)) {    
                    log.error("Clear of region " + regionName + " is already in progress.  Aborting.");    
                    // Let the client know we ignored their "clear" request.   
                    rfc.getResultSender().lastResult(false);    
                    return;    
                }    
                clearingRegionList.add(regionName);    
            }       

            if (!PartitionRegionHelper.isPartitionedRegion(region)) {    
                region.clear();    
                rfc.getResultSender().lastResult(true);    
            } else {
                // We are going to clear the region in a partitioned manner, each node only clearing    
                // the data in it's own node. So we need to get the "local" region for the node.    
                Region localRegion = PartitionRegionHelper.getLocalDataForContext(rfc);

                // Beware, this keySet() is a reference to the actual LIVE key set in memory. So    
                // we need to clone the set of keys we want to delete, otherwise we'll be looping    
                // through a live list and potentially deleting items that were added after the    
                // delete started.     
                List keyList = new ArrayList(localRegion.keySet());        

                // Once we have the keys, go ahead and set the lastResult to "true" to    
                // unblock the caller, because this could take a while. (The caller doesn't actually    
                // unblock until ALL nodes have returned "true".)    
                rfc.getResultSender().lastResult(true);           
                int regionSize = keyList.size();    
                log.info("Region " + regionName + " has " + regionSize + " entries to clear.");

                int count = 0;            
                for (Object key : keyList) {                                
                    //The "remove" method returns the object removed.  This is bad because it (sometimes?) causes    
                    //GemFire to try and deserialize the object, and that fails because we don't have the class on    
                    //our server classpath.  But if we invalidate first, it destroys the entry object without     
                    //deserializing it.  Then "remove" cleans up the key.   
                    try {    
                        localRegion.invalidate(key);    
                        localRegion.remove(key);    
                    } catch (EntryNotFoundException enfe) { //If the entry has disappeared (or expired) by the time we try to remove it,    
                                                            //then the GemFire API will throw an exception.  But this is okay.    
                        log.warning("Entry not found for key = " + key.toString(), enfe);    
                    }    
                    count++;    
                    // Every 10000 is frequent enough to give you a quick pulse, but    
                    // not so frequent as to spam your log.    
                    if (count % 10000 == 0) {    
                        log.info("Cleared " + count + "/" + regionSize + " entries for region " + regionName);    
                    }    
                }    
            }

            log.warning("Region cleared: " + regionName);            
            synchronized (clearingRegionList) {    
                clearingRegionList.remove(regionName);   
            }    
        } catch (RuntimeException rex) {    
            // Make sure we clean up our tracking list even in the unlikely event of a blowup.    
            clearingRegionList.remove(regionName);    
            log.error(rex.toString(), rex); // Log AND throw is bad, but from my experience, a RunTimeException    
                                            // CAN get sent all the way back to the client and never show   
                                            // up in gemfire.log. (If the exception happens before last result)    
            throw rex;    
        }             
    }

    @Override    
    public String getId() {    
        return "clear-region-function";    
    }        

    @Override    
    public void init(Properties arg0) { }

    @Override
    public boolean hasResult() { return true; }        

    @Override    
    public boolean isHA() { return true; }

    @Override    
    public boolean optimizeForWrite() {return true;}

}

答案 3 :(得分:0)

我们使用GemFire,最后我编写了一个功能来消灭整个区域。这比一次删除一个条目的简单客户端循环执行得快得多,因为函数是分布式的,并且每个节点只清除该节点的本地条目。

并且可以从gfsh执行函数,因此它非常易于使用。

如果可以使用,我可以共享此函数的源代码吗?

答案 4 :(得分:0)

您需要使用GemFire函数清除区域,这是一种非常快速且优化的方法,用于从gemfire区域删除记录,在以下github存储库中查找详细代码

POM:

       <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>GemFireRemoveAllDataFunction</groupId>
        <artifactId>GemFireRemoveAllDataFunction</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <build>
            <sourceDirectory>src</sourceDirectory>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.7.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>

    <dependencies>
        <dependency>
            <groupId>io.pivotal.gemfire</groupId>
            <artifactId>geode-core</artifactId>
            <version>9.6.0</version>
        </dependency>
    </dependencies>

</project>

功能:

package com.khan.viquar.gemfire;

import java.util.ArrayList;
import java.util.List;

import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.cache.execute.RegionFunctionContext;
import org.apache.geode.cache.partition.PartitionRegionHelper;


@SuppressWarnings("rawtypes")
public class ClearRegionRemoveAllDataFunction implements Function, Declarable {

    private static final long serialVersionUID = 11L;

    private static final int batchSize = 30000;

    @SuppressWarnings("unchecked")
    public void execute(final FunctionContext ctx) {
        if (ctx instanceof RegionFunctionContext) {
            final RegionFunctionContext rfc = (RegionFunctionContext) ctx;
            try {
                final Region<Object, Object> region = rfc.getDataSet();
                if (PartitionRegionHelper.isPartitionedRegion(region)) {
                    clear(PartitionRegionHelper.getLocalDataForContext(rfc));
                } else {
                    clear(region);
                }
                ctx.getResultSender().lastResult("Success");
            } catch (final Throwable t) {
                rfc.getResultSender().sendException(t);
            }
        } else {
            ctx.getResultSender().lastResult("ERROR: The function must be executed on region!");
        }
    }

    private void clear(final Region<Object, Object> localRegion) {
        int numLocalEntries = localRegion.keySet().size();
        if (numLocalEntries <= batchSize) {
            localRegion.removeAll(localRegion.keySet());
        } else {
            final List<Object> buffer = new ArrayList<Object>(batchSize);
            int count = 0;
            for (final Object k : localRegion.keySet()) {
                buffer.add(k);
                count++;
                if (count == batchSize) {
                    localRegion.removeAll(buffer);
                    buffer.clear();
                    count = 0;
                } else {
                    continue;
                }
            }
            localRegion.removeAll(buffer);
        }
    }

    public boolean hasResult() {
        return true;
    }

    public String getId() {
        return ClearRegionRemoveAllFunction.class.getSimpleName();
    }

    public boolean optimizeForWrite() {
        return true;
    }

    public boolean isHA() {
        return true;
    }
}